合并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略
- 其基本模式如下:
分解:把一个问题分解成与原问题相似的子问题
解决:递归的解各个子问题
合并:合并子问题的结果得到了原问题的解。
动态效果示意图:
分阶段:递归拆分子序列的过程。
治阶段:将两个已经有序的子序列合并成一个有序序列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| /** * 合并排序算法 * @param {Arry[number]} arr 待排序数组 */ function mergeSort(arr) { // 采用自上而下的递归方法 var len = arr.length; if (len < 2) {//只有1个数就返回 return arr; } var middle = Math.floor(len / 2),//中间值 left = arr.slice(0, middle),//左边数组 right = arr.slice(middle);//右边数组 return merge(mergeSort(left), mergeSort(right)); }
/** * 把两个数组合并排序 * @param {Arry[number]}} left 待合并数组 * @param {Arry[number]} right 待合并数组 */ function merge(left, right) { var result = [];
while (left.length && right.length) {//两个数组中都有值 //左边小于右边则把左边数组第一个放入结果中,否则把右边数组第一个放入结果 //同时删除该数组 if (left[0] <= right[0]) { result.push(left.shift()); } else { result.push(right.shift()); } }
//只有左边数组 while (left.length) result.push(left.shift());
//只有右边数组 while (right.length) result.push(right.shift());
return result; }
|
归并排序是稳定排序,它也是一种十分高效的排序,能利用完全二叉树特性的排序。每次合并操作的平均时间复杂度为O(n)
,总的平均时间复杂度为O(nlogn)
。而且,归并排序的最好,最坏,平均时间复杂度均为O(nlogn)
。