两种时间复杂度为的排序算法:归并排序和快速排序的JavaScript实现
这两天看了来自bilibili的左程云大佬的视频,这个算是一个小小的总结。
前边的时间复杂度为N^2的算法没有总结,个人感觉正常的思维就是插入排序这种,没有必要过多关注,只需要知道有插入、冒泡等算法及其基本原理就行了。
下面开始正题:
归并排序和快速排序的共同点都是将数据进行分割,然后再进行递归。
但是他们也存在着不同,归并排序是先将数据分割到极致,然后逐步实现其有序。
而快速排序则是先将其中的一部分有序,有序的部分将整体数据分割为三个部分,两个无序的部分和一个有序的部分,再分别对两个无序的部分进行递归,最终的到有序的结果。
具体详细过程参考各种资料。
下面是我的JavaScript代码供大家参考。
快速排序的实现
var arr = new Array(50000000);
//为数组填充数据,测试使用,自封装函数
randomArray(arr, 10000000);
console.log(arr);
function quickSort(arr,l,r){
var left = l;
var right = r;
//arr数要处理的数组,l是左方下标,r是右方下标
if(r-l<=0){
return;
}
swap(arr,r,l+parseInt(Math.random()*(r-l+1)));
var num = arr[r];
var i = l;//指针,指向待处理的数组元素
while(i<=r){
if(arr[i] < num){
//我自己写的用于数组交换的函数,因为感觉使用率挺高的,所以就抽离成了一个函数,需要时引用即可
swap(arr,i,l);
l++;
i++;
} else if(arr[i] > num){
swap(arr,i,r);
r--;
} else{
i++;
}
}
quickSort(arr,left,l-1);
quickSort(arr,r+1,right);
}
console.log(new Date().toLocaleString('cn',{hour12:false}));
quickSort(arr,0,arr.length-1);
console.log(new Date().toLocaleString('cn',{hour12:false}));
console.log(arr);
归并排序的实现
var arr = new Array(50000000);
randomArray(arr, 10000000);
console.log(arr);
function process (arr,L,R){
if(L == R){
return;
}
var mid = parseInt(L + (R - L) / 2);
process(arr,L,mid);//对数组的左半部分进行归并排序
process(arr,mid+1,R);//对数组的右半部分进行归并排序
mergeSort(arr,L,mid,R);//对两侧两个有序的数组进行归并排序
}
function mergeSort(arr,L,mid,R){
var help = new Array();
var p1 = L;//左侧数组的指针
var p2 = mid+1;//右侧数组的指针
while(p1 <= mid && p2 <= R){
arr[p1] <= arr[p2] ? help.push(arr[p1++]) : help.push(arr[p2++]);
}
while(p1 <= mid){
help.push(arr[p1++]);
}
while(p2 <= R){
help.push(arr[p2++]);
}
for(var i=0;i<help.length;i++){
arr[L+i] = help[i];
}
}
console.log(new Date().toLocaleString('cn',{hour12:false}));
process(arr,0,arr.length-1);
console.log(new Date().toLocaleString('cn',{hour12:false}));
console.log(arr);
我还对两种算法分别进行了效率测试,结果如下:
数据量 | 500w个数据 | 1000w个数据 | 5000w个数据 |
归并排序 | 约为6秒 | 约为10秒 | 约为60秒 |
快速排序 | 约为3秒 | 约为6秒 | 约为30秒 |
以上测试数据排除了与样本平均值测试差异较大的数据
每种算法每个数据量进行了20次测试。
另外个人在最后抛出一个小问题:快速排序有三种版本(有没有我也不知道),我个人写的是所谓的快排3.0。快排2.0是选取数组末尾的作为标记进行排序,而快排3.0是使用随机选取的方式选择标记。根据我个人的测试结果来看,两个版本的差距并没有多少,所以为什么要推出3.0的版本。