js算法:Merge Sort 归并排序

我的未来我决定 提交于 2019-12-25 21:28:45

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

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

归并排序的时间复杂度为nlogn

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!