快速排序,选择排序,直接插入,冒泡排序的javascript实现

时间:2020-12-05 22:08:20

快速排序:选取数组第一个元素作为基准元素,左右扫描数组,把大于等于基准元素的元素放在数组右边,小于等于基准元素的元素放在左边,把基准元素放在中间。一趟后数组基准元素左边的都小于等于基准元素,右边的都大于等于基准元素。对左边和右边分别递归调用自身。注意,在数组右边定位到要被换到左边的元素时,应该是把该元素直接覆盖掉i位置的元素,而不是i,j元素交换位置

    function quickSort(arr, s, e) {
var i = s,
j = e,
temp;
if (i < j) {//递归出口
temp = arr[s];//先记录下基准元素的值,因为后边移动元素的时候会覆盖
while (i != j) {
while (i < j && arr[j] >= temp) j--;
arr[i] = arr[j];//定位右边比基准元素小的元素,将其换到i所指的位置(会把i位置的元素覆盖,不过已经记录下来了)
while (i < j && arr[i] <= temp) i++;
arr[j] = arr[i];//定位左边比基准元素小的元素,把它换到j所指的位置
}
arr[i] = temp;//循环结束的时候i,j都指向同一个位置,把基准元素放上去
quickSort(arr, s, i - 1);//递归调用自身,i位置的元素已经归位,所以右端点是i-1
quickSort(arr, i + 1, e);
}
}

直接插入排序:数组分为有序区和无序区,每次把无序区的第一个元素插入到有序区的正确位置。初始时,有序区只有一个元素(因为只有一个元素所以有序),每次插入后有序区长度+1,一直到等于数组长度

 function insertSort(arr) {
for (var i = 1; i < arr.length; i++) {//初始有序区一个元素,所以从i=1开始把元素插入到有序区
var j = i - 1;//i是要被插入到有序区的元素的下标,只要与前面的元素比较就行了,不需要与自身比较
var temp = arr[i];//先记录下要被插入的元素,因为下面移动元素的时候会覆盖这个值
while (j >= 0 && arr[j] > temp) {//当arr[j]比temp大的时候,说明arr[j]最后应该在temp后面,并且它要往后移动一位,在扫描的时候就顺便把它往后移动一位,设置j>=0的原因是有可能要被插入的元素比有序区的所有元素都要小,当比较到-1的位置时,循环要终止
arr[j + 1] = arr[j];//把大于temp的元素后移动一位
j--
}
j++;//循环终止时j指向的是比temp小的元素,temp应该在这后面一位插入,所以j要再+1
arr[j] = temp;
}
}

直接插入排序递归版:从普通版中可以看出明显的递归关系,所以再写一个递归的,个人认为递归的优点是代码少,看上去简单,只是看上去而已,缺点是算法中没有细节,比较难理解。这里关键部分是有序区每次长度增加了1,所以下一次的区间右端点要+1

function insertSort2(arr, e) {
var temp = arr[e];
var e1 = e - 1;
if (e < arr.length) {
while (e1 >= 0 && arr[e1] >= temp) {
arr[e1 + 1] = arr[e1];
e1--;
}
e1++;
arr[e1] = temp;
insertSort2(arr, e + 1);
}
}

选择排序:同样也是分为有序区和无序区,与直接插入排序的区别是,每次从无序区挑选出最小的,然后只要放到有序区的末尾行了

function selectSort(arr) {
for (var i = 0; i < arr.length - 1; i++) {//做一次循环就有一个元素归位,只要有n-1个元素归位,剩下的一个自然是最大的,放在最后面
var minIndex = i;//只要记录好下标就行了,初次练习的时候移动了元素,复杂化了
for (var j = i; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
arr[i] = [arr[minIndex], arr[minIndex] = arr[i]][0];//交换元素,这里用了个小技巧,不用第三个变量就可以做到交换
}
}

冒泡排序

 function bubbleSort(arr) {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
arr[j] = [arr[j + 1], arr[j + 1] = arr[j]][0];
}

}
}
}