| 递归(Top-Down) | 非递归(Bottom-Up) | |
|---|---|---|
| 过程 | 先分裂到底,再逐层合并 | 从单元素开始,倍增归并长度 |
| 栈空间 | O(log n) 递归栈 + O(n) 辅助 | 无递归栈,仅 O(n) 辅助数组 |
| 时间 | O(n log n) | O(n log n) |
| 稳定性 | 稳定 | 稳定 |
算法思路:初始每个元素为长度 1 的有序子表;第 1 趟两两归并为长度 2;第 2 趟归并为长度 4;…… 直到归并长度 $\geq n$。
void MergeSort_NonRecursive(int A[], int n) {
int *temp = (int*)malloc(n * sizeof(int));
for (int len = 1; len < n; len *= 2) { // 归并长度倍增
for (int i = 0; i < n; i += 2*len) { // 每次处理 2*len 个元素
int left = i;
int mid = min(i + len, n); // 边界截断
int right = min(i + 2*len, n); // 边界截断
Merge(A, temp, left, mid, right);
}
}
free(temp);
}
例 1:$[8,4,5,7,1,3,6,2]$,$n=8$:
初始 [8,4,5,7,1,3,6,2] len=1 [4,8] [5,7] [1,3] [2,6] → 4,8,5,7,1,3,2,6 len=2 [4,5,7,8] [1,2,3,6] → 4,5,7,8,1,2,3,6 len=4 [1,2,3,4,5,6,7,8] → 完成(len=8 ≥ n)
例 2(不完整情况):$[3,1,4,1,5]$,$n=5$:len=1 → [1,3,1,4,5];len=2 → [1,1,3,4] 拼 [5];len=4 → 与 [5] 归并完成。中途残余子表直接拼接。
| 情况 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| 最好 | O(n log n) | O(n) |
| 平均 | O(n log n) | O(n) |
| 最坏 | O(n log n) | O(n) |
每趟归并 O(n),共 $\log n$ 趟 → O(n log n)。稳定排序(merge 时相等元素取前一个子表者)。
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。