js算法:Merge Sort 歸併排序

Merge Sort : 歸併排序,把一個大問題分解成若干相同的小問題,解決小問題後,合併小問題結果,最終把大問題解決. 例如要排序數組 originArr = [2, 5, 3, 8, 9, 6, 3, 4, 2] 先把問題分解爲排序 leftArr = [2, 5, 3, 8, 9] 和 rightArr = [6, 3, 4, 2]兩個小數組,而後合併leftArr和rightArr,當排序leftArr的時候發現問題仍是太複雜, 再把leftArr分解爲 leftArr1 = [2, 5, 3] 和 rightArr1 = [8, 9] ...以此遞歸調用,直到 leftArrN = [2]...數組

//分治法排序
var originArr = [2, 5, 3, 8, 9, 6, 3, 4, 2]
let startTime = new Date().valueOf();
console.info("原始數組:", originArr)
function mergeSort(arr, from, to) {
  //尋找合適的分割點
  let mid = parseInt((to + from) / 2);
  if (to > from) {    //若是 to!= from 說明問題仍是太複雜,遞歸調用分解問題
    mergeSort(arr, from, mid);
    mergeSort(arr, (mid+1), to);
    //合併左邊已經排好序的,和右邊已經排好序的
    merge(arr, from, mid, to);
  }
}

function merge(arr, from, mid, to) {
  let leftArr = [];
  let rightArr = [];
  //先把arr左邊排好序的部分扔到臨時數組leftArr中
  for(let i=from; i<= mid; i++) {
    leftArr.push(arr[i]);
  }
  //先把arr右邊排好序的部分扔到臨時數組rightArr中
  for(let j=mid+1; j<= to; j++) {
    rightArr.push(arr[j]);
  }
  //合併規則是,每次比較左邊和右邊最上面的值,把比較小的扔到arr[n]中,當左邊沒有了或者右邊沒有了,則把對應的另一個數組剩下的值依次放入到arr[n]中
  let i=0, j=0;
  for(let n=from; n<= to; n++) {
    //左邊數組沒有值了,把右邊數組剩下的值依次扔到arr[n]中
    if (i>= leftArr.length) {
      arr[n] = rightArr[j];
      j++;
      continue;
    }
    //右邊數組沒有值了,把左邊數組剩下的值依次扔到arr[n]中
    if (j >= rightArr.length) {
      arr[n] = leftArr[i];
      i++;
      continue;
    }
    //若是左邊右邊數組都有值,把二者比較小的那個扔到arr[n]中
    if (leftArr[i] > rightArr[j]) {
      arr[n] = rightArr[j];
      j++;
    } else {
      arr[n] = leftArr[i];
      i++;
    }
  }
  // console.info(`分隔點:${from}, ${mid}, ${to}, 合併完成後:`, arr)
}

mergeSort(originArr, 0, originArr.length-1);
console.info("最終排序結果:", originArr)
let endDate = new Date().valueOf()
console.info("花費時間:", endDate - startTime)

打印結果:

原始數組: [ 2, 5, 3, 8, 9, 6, 3, 4, 2 ]
最終排序結果: [ 2, 2, 3, 3, 4, 5, 6, 8, 9 ]
花費時間: 36

歸併排序的時間複雜度爲nlogncode

相關文章
相關標籤/搜索