经典排序算法和JS实现案例分析

人工智能

621人已加入

描述

经典排序算法 冒泡排序 原理:

1.比较相邻的元素,如果第一个比第二个大,就交换位置。
2.重复以上步骤,依次得出最大值,次大值。。。。
3.重复以上步骤,直到没有任何一对数字需要比较

算法分析:

1.若文件的初始状态是正序,一趟扫描完成排序。所需要的关键字的比较次数C和记录移动的次数M达到最小值:Cmin=n-1,Mmin=0,故冒泡排序的时间复杂度O(n);
2.若初始文件是反序的,需要进行n-1趟排序。每趟排序要进行n-i(1<=i<=n-1)次关键字的比较,且每次比较都必须移动记录3次(比如交换a[i-1]和a[i];tmp=a[i-1];a[i-1]=a[i];a[i]=tmp)来达到交换记录的位置。此时,比较和移动次数都达到最大值:Cmax=n*(n-1)/2=O(n2);Mmax=3n*(n-1)/2=O(n2), (根据等差数列求得) 故冒泡排序的最坏的时间复杂度是O(n2)。
综上两点,冒泡排序总的平均时间复杂度为O(n2);
总结:平均时间复杂度:O(n2), 稳定度:稳定, 空间复杂度:O(1)

代码实现:vararr=[1,5,3,2];functionbubbleSort(arr){for(leti=0,l=arr.length;ifor(letj=i+1;jif(arr[i]>arr[j]){lettemp=arr[i]; arr[i]=arr[j]; arr[j]=temp; } } }returnarr; } bubbleSort(arr); 选择排序 原理:每趟从待排序的记录中选出关键字最小的记录,顺序放到末尾,直到全部排序结束

1.从待排序中,找到最小的元素
2.如果最小元素不在排序序列的第一个元素,和第一个元素进行交换
3.从剩下的n-1个元素中,找出最小的元素,重复1,2步骤

算法分析:

1.时间复杂度:O(n2)
2.空间复杂度:O(1)

代码实现:vararr1=[5,3,2,1];functionselectSort(arr){letlen=arr.length,minIndex;//minIndex记录最小的索引for(vari=0;iif(arr[j]if(i!=minIndex){vartemp =arr[i]; arr[i]=arr[minIndex];arr[minIndex]=temp;} }returnarr; } selectSort(arr1); 插入排序/折半排序(insertion sort) 原理:插入排序的思想有点像打扑克牌时候,我们插入扑克牌的做法。一般打牌的时候,我们都是把抓到的牌按顺序放到已经按顺序排好的牌中。

1.将第二个位置的数字,和左面的数字比较,放入合适的位置(相当于手中有牌,又抓了一张牌)
2.将i个位置的数字,和其所在位置的左面的数字依次比较,放入合适的位置
3.重复以上步骤,直到排序完成。

算法分析:

1.时间复杂度:O(n2)
2.空间复杂度:O(1)

代码实现: var arr1=[5,4,3,2];functioninsertionSort(arr){var cur,preIndex;for(vari=1;i=0&& arr[preIndex]>cur){ arr[preIndex+1]=arr[preIndex]; preIndex--; }arr[preIndex+1]=cur; }returnarr; }insertionSort(arr1); 归并排序(merge sort) 原理:是将两个顺序序列合并成一个顺序序列的方法。

 

算法分析:

1.算法稳定性:稳定
2.时间复杂度:O(n*log2n),归并排序的形式就是一棵二叉树,它需要遍历的次数就是二叉树的深度,而根据完全二叉树可以得出
3.空间复杂度:n

代码实现:functionmergeSort(arr){if(arr.length==1){returnarr; }//首先将无序数组划分为两个数组varmid =Math.floor(arr.length/2);varleft = arr.slice(0,mid);varright = arr.slice(mid);returnmerge(mergeSort(left),mergeSort(right)); }functionmerge(left,right){varre=[];while(left.length>0&& right.length>0){if(left[0]这段合并排序的代码相当简单直观,但是mergeSort()函数会导致很频繁的自调用。一个长度为n的数组最终会调用mergeSort() 2*n-1次,这意味着如果需要排序的数组长度很大会在某些栈小的浏览器上发生栈溢出错误。
补充:浏览器栈的大小限制,可以用如下的代码

 

varcnt =0;try{ (function(){cnt++;arguments.callee(); })(); }catch(e) { console.log(e.message, cnt); }

为了防止遇到栈溢出的代码,将递归改为了迭代:

functionmerge(left, right){varresult = [];while(left.length && right.length) {if(left[0] < right[0]) result.push(left.shift());elseresult.push(right.shift()); }returnresult.concat(left, right); }functionmergeSort(a){if(a.length ===1)returna;varwork = [];for(vari =0, len = a.length; i < len; i++) work.push([a[i]]); work.push([]);// 如果数组长度为奇数for(varlim = len; lim >1; lim = ~~((lim +1) /2)) {for(varj =0, k =0; k < lim; j++, k +=2) work[j] = merge(work[k], work[k +1]); work[j] = [];// 如果数组长度为奇数}returnwork[0]; } 快速排序(quick sort) 原理:是冒泡排序基础上的递归分治法

1.比较全面你的一个解释网址,我喜欢

算法分析:

1.最坏时间复杂度O(n2)
2.平均时间复杂度:O(nlogn)

functionquickSort(arr){if(arr.length<=1){ return arr; }let leftArr =[]; let rightArr =[]; let q = arr[0];for(leti=1,l=arr.length;ii++){ if(arr[i]>q) { rightArr.push(arr[i]); }else{ leftArr.push(arr[i]); }}return[].concat(quickSort(leftArr),[q],quickSort(rightArr));
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分