排序算法总结二(JavaScript)
2017-08-10 16:05
260 查看
1、归并排序(自顶向下)
复杂度: O(nlogn) 稳定
保留副本需要开辟额外n个存储空间,以空间换取时间效率
2、归并排序(自底向上)
3、快速排序(三路快排序)
复杂度: O(nlogn) 不稳定
不需要开辟额外空间
4、堆排序
复杂度: O(nlogn) 不稳定
原地堆排序,不需要开辟额外空间
复杂度: O(nlogn) 稳定
保留副本需要开辟额外n个存储空间,以空间换取时间效率
//将左右两部分数组进行归并,保留原数组的一个副本,一个一个比较左右两个部分数组元素的大小,将副本的相应元素放到数组中 function __merge(arr,l,mid,r){ var copy=[]; for(var m=l;m<=r;m++){ copy[m]=arr[m]; } var i=l,j=mid+1; for(var k=l;k<=r;k++){ if(i>mid){ //左边部分已完成归并 arr[k]=copy[j]; j++; } else if(j>r){ // 右边部分已完成归并 arr[k]=copy[i]; i++; } else if(copy[i]<copy[j]){ //左边部分的元素大,将该元素添加到数组中,左边索引 i 右移 arr[k]=copy[i]; i++; } else{ arr[k]=copy[j]; //右边部分的元素大,将该元素添加到数组中,右边索引 j 右移 j++; } } } //递归调用归并排序函数对整个数组进行排序 function __mergeSort(arr,l,r){ if(l>=r){ return; } var mid=Math.floor((l+r)/2); __mergeSort(arr,l,mid); __mergeSort(arr,mid+1,r); //若左边最大值比右边最小值大,则进行归并操作,否则表示两部分已有序,不需要再进行归并 if(arr[mid]>arr[mid+1]){ __merge(arr,l,mid,r); } } function mergeSort(arr){ var n=arr.length; __mergeSort(arr,0,n-1); return arr; }
2、归并排序(自底向上)
function __merge(arr,l,mid,r){ var copy=[]; for(var m=l;m<=r;m++){ copy[m]=arr[m]; } var i=l,j=mid+1; for(var k=l;k<=r;k++){ if(i>mid){ arr[k]=copy[j]; j++; } else if(j>r){ arr[k]=copy[i]; i++; } else if(c c324 opy[i]<copy[j]){ arr[k]=copy[i]; i++; } else{ arr[k]=copy[j]; j++; } } } //若不进行优化 则可以用来对链表进行排序,因为排序中没有用到数组的下标 function mergeSortBU(arr){ var n=arr.length; var size,i; //分轮次进行归并,每轮归并的元素数量为size for(size=1;size<n;size+=size){ //每轮归并分组进行 for(i=0;i+size<n;i+=size+size){ //优化:如果两边已经有序就不在进行归并 if(arr[i+size-1]>arr[i+size]){ __merge(arr,i,i+size-1,Math.min(i+size+size-1,n-1)); //防止越界 } } } return arr; }
3、快速排序(三路快排序)
复杂度: O(nlogn) 不稳定
不需要开辟额外空间
function __quickSort(arr,l,r){ if(l>=r){ return; } //三路: 分为三部分 比参考元素小:arr[l+1....lt] 等于参考元素: arr[lt+1....i] 大于参考元素: arr[gt...r]; var v=arr[l]; //取第一个元素为参考 var lt=l; var gt=r+1; var i=l+1; while(i<gt){ if(arr[i]<v){ //比参考元素小的与lt+1交换 var temp=arr[i]; arr[i]=arr[lt+1]; arr[lt+1]=temp; lt++; i++; } else if(arr[i]>v){ //比参考元素大的与gt-1交换 var temp2=arr[i]; arr[i]=arr[gt-1]; arr[gt-1]=temp2; gt--; } else{ //与参考元素相等直接右移 i++; } } //将参考元素放到合适的位置 var temp1=arr[l]; arr[l]=arr[lt]; arr[lt]=temp1; //递归对左右两部分进行快排序 __quickSort(arr,l,lt-1); __quickSort(arr,gt,r); } function quickSort(arr){ var n=arr.length; __quickSort(arr,0,n-1); return arr; }
4、堆排序
复杂度: O(nlogn) 不稳定
原地堆排序,不需要开辟额外空间
//left child (i)=2*i+1 right child (i)=2*i+2 parent(i)=(i-1)/2 //最后一个非叶子节点的索引: (n-1)/2 //构建最大堆的函数 function shiftDown(arr,n,k){ //要保证左孩子在n范围内 并且该节点比其左孩子或右孩子中任意一个小 while((2*k+1)<n && (arr[k]<arr[2*k+1] || (arr[k]<arr[2*k+2]&&2*k+2<n))){ //有右孩子且右孩子比左孩子大 if(2*k+2<n&&arr[2*k+1]<arr[2*k+2]){ [arr[k],arr[2*k+2]]=[arr[2*k+2],arr[k]]; k=2*k+2; }else{ //包含右孩子比左孩子小和没有右孩子两种情况 [arr[k],arr[2*k+1]]=[arr[2*k+1],arr[k]]; k=2*k+1; } } } function heapSort(arr){ var n=arr.length; //将数组构建成最大堆 for(var i=Math.floor((n-1)/2);i>=0;i--){ shiftDown(arr,n,i); } for(var j=n-1;j>0;j--){ //堆顶元素最大,每次将堆顶元素与最后一个元素交换 [arr[j],arr[0]]=[arr[0],arr[j]]; //如果待排序元素数大于1,则进行堆重构;等于1说明已经完成排序 if(j>1){ shiftDown(arr,j,0); }else{ break; } } return arr; }
相关文章推荐
- JavaScript学习总结(15)——十大经典排序算法的JS版
- 十大经典排序算法总结(JavaScript描述)
- 排序算法总结一(JavaScript)
- JavaScript实现排序算法总结
- 十大经典排序算法总结(JavaScript描述)
- 十大经典排序算法总结(JavaScript描述)
- javascript常用排序算法总结
- javascript常见排序算法总结
- 排序算法总结(Javascript版本)
- 常见的排序算法总结(JavaScript)
- 如何写好 JavaScript (二) ——《高性能 JavaScript》章节总结
- 【知识整理】javascript基础语法总结(5)——数组
- JavaScript 分号使用总结
- javascript中字符串常用操作总结、JS字符串操作大全
- java基本排序算法总结(一)——冒泡排序法
- Javascript 正则表达式总结
- 排序算法(个人总结)
- 【转】排序算法总结(摘至WIKI)
- 排序算法总结----快速排序
- 优化javascript的执行效率一些方法总结