遞歸javascript
上一篇blog裏,用js實現了quicksort算法,quicksort算法是一個遞歸調用過程。java
遞歸是一種很是強大的編程思想,它普遍的的存在於各類語言當中,尤爲lisp的各類方言中,大量的使用遞歸來實現循環操做。算法
還有一本小書叫《The litter schemer》,就是讓編程的人遞歸的思考問題(thinking recursively)。編程
本篇呈接上篇,是對遞歸思想的實踐——在學習常見的算法的同時,運用遞歸思想。數組
理解了遞歸思想,之前以爲挺難的算法也以爲不是想象的那麼難了。ide
mergsort in javascript函數
function first(l){ return l[0]; } function rest(l){ return l.slice(1); } /** 實現2 * l1 l2 是已經從小到大排序好的數組 * 返回一個l1 l2合併後的,從小到大排序好的數組 * */ function mergelist(l1,l2){ var ret if(l1.length == 0){ ret = l2; }else if(l2.length == 0){ ret = l1; }else if(first(l1)>first(l2)){//將小的放前面 ret = [].concat(first(l2), mergelist(l1,rest(l2))) }else{ ret = [].concat(first(l1),//將小的元素放前面 mergelist(l2,rest(l1))) } return ret; } // console.log(mergelist([2,3],[1,4,5])); // console.log(mergelist([1,4,5],[2,3])); // --> [ 1, 2, 3, 4, 5 ] // 下面這個操做是對一組數數組排序的最小單位排序操做——由於 // 一個包含任意元素的數組的排序最終都能逐漸的遞歸細分爲比較兩個元素的大小 // 切分操做由下面的divide函數來完成 // console.log(mergelist([5],[2])); // --> [ 2, 5 ] // 實現3中的拆分 // 將一個數組分爲兩部分 function divide(l){ var len = l.length , mid = Math.floor(len/2); return [l.slice(0,mid),l.slice(mid,len)] } // console.log(divide([1,4,5,2,3])); //--> [ [ 1, 4 ], [ 5, 2, 3 ] ] // 總體實現 function mergesort(l1){ var ab = divide(l1) , a = ab[0] , b = ab[1]; if(a.length == 0){ return b; }else if(b.length == 0){ return a; }else if(a.length == 1){ return [].concat(mergelist(a,mergesort(b))); }else if(b.length == 1){ return [].concat(mergelist(b,mergesort(a))); }else{ return [].concat(mergelist(mergesort(a), mergesort(b))); } } console.log(mergesort([5,2,3,4])); console.log(mergesort([5,3,4])); // console.log(mergesort([1,4,5,2,3])); // 注意[].concat方法的運用 // [].concat(1,[2,3]) -> [1,2,3] // [].concat([1],[2,3]) -> [1,2,3] // [].concat(1,2,3) -> [1,2,3]