merge sort 的javascript實現

遞歸javascript

上一篇blog裏,用js實現了quicksort算法,quicksort算法是一個遞歸調用過程。java

遞歸是一種很是強大的編程思想,它普遍的的存在於各類語言當中,尤爲lisp的各類方言中,大量的使用遞歸來實現循環操做。算法

還有一本小書叫《The litter schemer》,就是讓編程的人遞歸的思考問題(thinking recursively)。編程

本篇呈接上篇,是對遞歸思想的實踐——在學習常見的算法的同時,運用遞歸思想。數組

理解了遞歸思想,之前以爲挺難的算法也以爲不是想象的那麼難了。ide

mergsort in javascript函數

  1. 最簡單的狀況是對兩個元素的數組排序;
  2. 若是兩個數組已經排序好了,那麼,再將這兩個數組合併爲一個有序的數組是比較容易的;
  3. 一個混亂的數組,總能將其分紅兩部分,再將分紅的兩部分再分爲兩部分,直到有一個部分只包含兩個元素,那麼就回到第1步的狀況,對兩個元素的數組進行排序;
  4. 這是一個遞歸過程
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]
相關文章
相關標籤/搜索