希尔排序
在插入排序的基础上,只不过比较的步长不一样,插入排序比较步长一直是1(即一个一个的比较)。希尔排序的步长第一次一般设置为gap=Math.floor(arr.length/2),之后依次将步长设置为gap/2,直到步长变为1,这个时候彻底转化成插入排
测试时间普通排序算法10万条数据就已经时间很久了,但是希尔排序都可以处理千万条数据,时间大概为2000毫秒,一亿条数据没有测试
以下的数据是测试10万条数据的普通排序算法和1000万的希尔排序算法,时间真的差的很多
时间复杂度:
稳定性:不稳定
function shellSort(arr){
//外层循环为步长,直到步长为1不再循环
for(var gap = Math.floor(arr.length/2);gap >0;gap = Math.floor(gap/2)){
//步长为gap的插入排序,方法同插入排序,只不过原来的j--变成了 j -= gap
for(var i=gap;i<arr.length;i++){
var temp = arr[i];
for(var j = i-gap;j>=0;j -= gap){
if(temp >= arr[j]){
break;
}else{
arr[j+gap] = arr[j];
arr[j] = temp;
}
}
}
}
return arr;
}
归并排序
实现原理:将一系列排好序的子序列合并成一个大的完整有序序列
时间复杂度:
稳定性:
测试千万数据过程中发现时间没有希尔排序快
//合并两个数组
function mergeArray(left,right){
var arr = [];
var i=0;
var j=0;
while(i<left.length && j<right.length){
if(left[i] <= right[j]){
arr.push(left[i]);
i++;
}else{
arr.push(right[j]);
j++;
}
}
while(i<left.length){
arr.push(left[i]);
i++;
}
while(j<right.length){
arr.push(right[j]);
j++;
}
return arr;
}
//将数组分成两个数组(一直递归的分,知道length长度为1则不分),并将这两个数组有序的组合起来
function mergeSort(arr){
var mid,left,right;
if(arr.length<=1){
return arr;
}else{
mid = Math.floor(arr.length/2);
left = arr.slice(0,mid);
right = arr.slice(mid);
return mergeArray(mergeSort(left),mergeSort(right));
}
}
快速排序
快速排序是处理大数据最快的排序算法之一,它是一种分而治之的算法。通过递归的方法将数据分解为包含较小元素和较大元素的不同子序列,不断重复直到数据有序
算法首先在列表中选择一个元素作为基准值。数据排序围绕基准值进行,将列表中小于基准值的元素移到数组的底部,将大于基准值的元素移到数组的顶部
快速排序适合大型数据,小的数据反而效率不高
时间复杂度:
稳定性:
function qSort(arr){
if(arr.length <= 1){
return arr;
}
var left = [];
var right = [];
var mid = arr[0];
for(var i=1;i<arr.length;i++){
if(arr[i] <= mid){
left.push(arr[i]);
}else{
right.push(arr[i]);
}
}
return qSort(left).concat(mid,qSort(right));
}
存在问题:当数据量大的时候提示too much recursion