常见几种排序算法
- 选择排序
- 插入排序
- 快速排序
- 冒泡排序
1、选择排序
原理
首先,找到数组中最小的那个元素,其次,将它和数组的第 一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)。再次,在剩下的元素中 找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。这种方法 叫做选择排序,因为它在不断地选择剩余元素之中的最小者。
特点
对于长度为 N 的数组,选择排序需要大约 N2/2 次比较和 N 次交换。
交换过程
代码
function sort(arr){
for(let i=0, len = arr.length; i < len; i++){
let min = i;//声明最小值下标
//从当前位置往后找出其中的最小值
for(let j=i; j<len; j++){
arr[min]>arr[j]&&(min=j);
}
//交换当前值和最小值
let temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
return arr;
}
2、插入排序
原理
先假定将n个元素的数列分为已有序和无序两部分。然后将无序数列的第一个元素与有序数列的元素从后往前逐个比较,找出插入位置,将该元素插入到有序数列的合适位置中。这种方法 叫做插入排序。
特点
对于随机排列的长度为 N 且主键不重复的数组,平均情况下插入排序需要~ N*N/4 次比较以及~ N*N/4 次交换。最坏情况下需要~N*N/2 次比较和~ N*N/2 次交换,最好情况下需要 N-1 次比较和 0 次交换。
交换过程
代码
function sort(arr){
//从第2个元素开始遍历
for(let i=1, len = arr.length; i < len; i++){
let key = arr[i];//取出要比较的数
let index = 0;
//从后向前遍历
for(let j=i-1; j>-1; j--){
if(key<arr[j]){
//向后退1位
arr[j+1]=arr[j];
}else{
//记住后面位置的下标并退出循环,因为前面的数肯定没key大
index = j+1;
break;
}
}
//将要比较的数插入到准确位置
arr[index] = key;
}
return arr;
}
3、快速排序
原理
这是一种分治的排序算法。首先,将一个数组分成两个子数组,将两部分独立地排序。切分的位置取决于数组的内容,比如找出数组中差不多中间值的值,把小于这个值的数放在左边,大于这个数的放在右边。然后再将左边部分排序,也是上述过程,采用递归调用即可;右边部分也是如此。而当两个子数组都有序时,整个数组就都有序了。这种方法 叫做快速排序。
交换过程
大致交换过程
具体交换过程
lo - low ; hi - high ;
对于切分使得数组满足以下三个条件:
1、对于某个 j,a[ j ] 已经排定;
2、a[ lo ] 到 a[ j -1 ] 中的所有元素都不大于a[ j ] ;
3、a[ j +1] 到 a[ hi ] 中的所有元素都不小于a[ j ] ;
代码
4、冒泡排序
原理
将前后每两个数进行比较,较大的数往后排,一轮下来最大的数就排到最后去了。然后再进行第二轮比较,第二大的数也排到倒数第二了,以此类推。这种方法 叫做冒泡排序。
交换过程
代码
function sort(arr){
//总走了len-1趟
for(let i=0, len = arr.length; i < len-1; i++){
for(let j=0;j<len-i-1;j++){
//两两比较,
if(arr[j]>arr[j+1]){
//大的放后,小的放前
let temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}