归并排序

2018/5/19 Javascript算法

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

把长度为n的输入序列分成两个长度为n/2的子序列; 对这两个子序列分别采用归并排序; 将两个排序好的子序列合并成一个最终的排序序列。

归并操作的工作原理如下: 第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置 第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针超出序列尾 将另一序列剩下的所有元素直接复制到合并序列尾

最佳情况:T(n) = O(n) 最差情况:T(n) = O(nlogn) 平均情况:T(n) = O(nlogn)

const mergeSort = (arr) => {
  let len = arr.lenght;
  if (len < 2) {
    return arr;
  }
  let m = (len >> 1), //通过位运算符,将len取为一半。
    left = array.slice(0, m),
    right = array.slice(m); //拆分为两个子数组
  return merge(mergeSort(left), mergeSort(right));//子数组继续递归拆分,然后再合并
}
const merge = (left, right) => { //合并两个子数组
  let res = [];
  while (left.length && right.length) {
    let item = left[0] <= right[0] ? left.shift() : right.shift();//注意:判断的条件是小于或等于,如果只是小于,那么排序将不稳定.
    result.push(item);
  }
  return result.concat(left.length ? left : right);
}