归并算法的JS实现及分析(分治,递归,归并)
2017-10-20 02:03
573 查看
有趣的扑克牌排序帮助你理解归并算法
思考一下有趣的扑克牌排序,比如你的面前有两堆(A堆和B堆)牌,牌面朝上,你每次比较两堆牌最顶上的两张牌,选择较小的一张,放在另一个堆(C堆),重复此过程,直到A堆和B堆的牌耗尽。这个过程就是归并。但此时你得到的C堆的牌可能不是升序的。因为你的A堆或B堆可能不是升序的。想象下你的A堆有5,3,………,B堆有12,1,…………。这时你得到的C堆就会是5,3,………..。其中的原因就是我刚刚说的A堆或B堆可能不是升序的。但是如果将A堆进行拆分为A1和A2,再将A1拆分为A11和A12,A2拆分为A21和A22,然后继续往下拆,直到,拆到两边各剩一张牌。这个过程就是分治(分治分治分开治理嘛)。这个时候再对两边各剩一张牌进行归并,得到一定是一个升序的两张牌。将所有的两边各一张牌进行归并,得到许多升序的两张牌,再将两边都为升序的两张牌进行归并,就会得到升序的四张牌。以此类推,就会归并得到升序的A堆和B堆,也就解决了刚刚A堆或B堆可能不是升序的问题。不断的归并又可以用递归来解决。所以,分治,递归,归并就完美的构成了我们的归并算法。
归并算法的JS实现
//假设这就是我们的一堆杂乱无序的牌 let arr=[1,2,4,7,53,8,33,64,5,2,47,61,7]; //归并 function merge(arr,l,m,r){ //左边的牌压入leftArr,右边的牌压入rightArr //--------start----------------- let leftArrLen=m-l+1; let rightArrLen=r-m; let leftArr=[]; let rightArr=[]; for(var i=0;i<leftArrLen;i++){ leftArr[i]=arr[l+i]; } for(var j=0;j<rightArrLen;j++){ rightArr[j]=arr[m+j+1]; } //--------end----------------- //为两边的两堆牌的最后设置一张无求大的牌,这样在一堆牌耗尽之后暴漏出无求大 //牌,另一堆的牌一定小于这张牌就只会抽取另一堆的牌了 leftArr[leftArrLen]=Infinity; rightArr[rightArrLen]=Infinity; //复用i,j减少内存开销,设置为0代表从两堆牌的顶上开始比较 i=0; j=0; //k到r就是两堆牌一共的牌数,我们只需要重复这么多次就好,因为每次必定抽出一张 //牌 for(var k=l;k<=r;k++){ //比较抽出较小牌,并通过++j;或++i;达到暴漏出下一张牌的目的 if(leftArr[i]>rightArr[j]){ arr[k]=rightArr[j]; ++j; }else{ arr[k]=leftArr[i]; ++i; } } } //分治和递归 //通过l<r判断,进行分治(m=Math.floor((l+r)/2)), //再进行递归mergeSort(arr,l,m);mergeSort(arr,m+1,r); //再由最少的两张牌开始归并 merge(arr,l,m,r); function mergeSort(arr,l,r){ if(l<r){ let m=Math.floor((l+r)/2); mergeSort(arr,l,m); mergeSort(arr,m+1,r); merge(arr,l,m,r); } } mergeSort(arr,0,arr.length-1); console.log(arr);
node运行结果:
相关文章推荐
- 汇编语言实现递归阶乘算法代码分析(8)
- JS基于递归实现网页版计算器的方法分析
- 最近点对问题的分治算法分析与实现
- 算法设计与分析 快速排序的递归实现算法
- 归并算法 c#实现(递归实现)
- 算法分析之Ackerman函数的递归实现算法
- k路归并算法的分析和实现
- 【算法设计与分析】递归与分治----2.4 排列问题
- 算法设计与分析之递归与分治策略
- 算法 插入排序 的 JS实现及时间复杂度分析
- 【计算机算法分析】递归与分治策略——二分搜索与集合划分问题
- Java归并算法递归实现
- k路归并算法的分析和实现
- 求子集问题算法分析与实现(递归、非递归)
- 分治与递归(算法分析与设计)
- [Java算法分析与设计]二叉树非递归实现遍历
- 使用递归下降算法分析数学表达式 -- 基于堆栈的计算器实现算法
- 整数划分问题算法分析与实现(递归)
- 全排列问题算法分析与实现(递归、非递归)
- 栈与递归的实现:n阶Hanoi塔的算法分析与源码