合并排序算法遵循分治策略;
1. 先将数组细分到只有一个元素
2. 然后依次合并排序数组(核心是合并两个已排序数组)
算法复杂度:
时间复杂度: 临近上界和临近下界全部都是O(nlgn), Ω(nlgn)
(可以通过数学推导法得出)
空间复杂度:O(n)
代码:
// 排序数组A[p,r)的顺序; function merge_sort(A, p, r) { // 递归基准条件 if (r-p<2) return; //递归条件 const q = Math.ceil((p+r)/2); merge_sort(A,p,q); merge_sort(A,q,r); merge(A,p,q,r); }
// [p,q)和[q,r)合并两个有序(递增)数组 function merge(A, p, q, r) { const A1 = A.slice(p,q); const A2 = A.slice(q,r); // 两个数组添加哨兵;优化边界条件的判断 A1.push(Number.MAX_SAFE_INTEGER); A2.push(Number.MAX_SAFE_INTEGER); // 循环不变式 for (k=p, i=0, j=0; k<r; k++) { // i代表A1的循环变量;j代表A2的循环变量 // k代表A的循环变量;用于回写A A[k]=A1[i]>A2[j] ? A2[j++] : A1[i++]; } }
测试用例:
const A1 = [1,3,6,3,23,6,313,23,3,23,34]; merge_sort(A1,0,A1.length); console.log(A1); // [1, 3, 3, 3, 6, 6, 23, 23, 23, 34, 313] const A2 = [67,232,23,78,12,70]; merge_sort(A2, 1, 4); //排序[1,4) console.log(A2); // [67,23,78,232,12,70]