归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:
- 自上而下的递归
- 自下而上的迭代;
算法步骤
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
- 重复步骤 3 直到某一指针达到序列尾;
- 将另一序列剩下的所有元素直接复制到合并序列尾。
复杂度
| 标题 | 数据 |
|---|---|
| 平均时间复杂度 | O(nlogn) |
| 最好情况 | O(nlogn) |
| 最坏情况 | O(nlogn) |
| 空间复杂度 | O(n) |
| 排序方式 | Out-place |
| 稳定性 | 稳定 |
代码演示
function mergeSort(list) {
function Sort(list, start, end) {
if (start >= end) return;
//选择中位值开始递归
let mid = (start + end) / 2 | 0;
Sort(list, start, mid);
Sort(list, mid + 1, end);
let temp = [],//归位数组
index = 0,//归位初始化下边
p1 = start,//左边的初始指针
p2 = mid + 1;//右边的初始指针
//并-左右两边还有剩余元素,进行比较归位
while (p1 <= mid || p2 <= end) {
//右边为空时或者左右边都有值但是左边小
if (p2 > end || p1 <= mid && list[p1] < list[p2]) {
//左边并进去
temp[index++] = list[p1++]
} else {
//右边并进去
temp[index++] = list[p2++]
}
}
//并-合并成原来的数组
for (let i = start; i <= end; i++) {
//通过减去start找到归位点
list[i] = temp[i - start]
}
return list
}
return Sort(list, 0, list.length - 1)
}
过程输出
结果