每天学一个算法-- 归并排序(Merge Sort)

📘 归并排序(Merge Sort)


1. 问题定义

给定数组 (A[1...n]),要求输出:

A\[1\]≤A\[2\]≤⋯≤A\[n\]\]\[ A\[1\] \\le A\[2\] \\le \\dots \\le A\[n\] \]\[A\[1\]≤A\[2\]≤⋯≤A\[n\]

2. 核心思想

归并排序同样基于:

分治(Divide and Conquer)

但与快速排序的关键区别:

快排:先划分,再递归(Partition-based)
归并:先递归,再合并(Merge-based)

3. 核心术语

3.1 分治(Divide)

将数组递归拆分为:

A\[l..r\]→A\[l..mid\]+A\[mid+1..r\]\]\[ A\[l..r\] \\rightarrow A\[l..mid\] + A\[mid+1..r\] \]\[A\[l..r\]→A\[l..mid\]+A\[mid+1..r\]

直到每个子数组长度为 1

3.2 合并(Merge)

定义:

将两个已排序数组合并为一个有序数组

关键性质:

  • 输入:两个有序序列
  • 输出:一个有序序列

3.3 稳定性(Stability)

归并排序是:

稳定排序

因为合并时:

  • 相等元素保持原顺序

3.4 非原地(Out-of-place)

归并排序需要:

  • 额外数组辅助合并

空间复杂度为:

O(n)\]\[ O(n) \]\[O(n)

4. 算法结构


4.1 主函数

text 复制代码
MergeSort(A, l, r):
    if l >= r:
        return

    mid = (l + r) // 2

    MergeSort(A, l, mid)
    MergeSort(A, mid+1, r)

    Merge(A, l, mid, r)

4.2 合并函数

text 复制代码
Merge(A, l, mid, r):
    创建临时数组 temp

    i = l
    j = mid + 1

    while i ≤ mid and j ≤ r:
        if A[i] ≤ A[j]:
            temp.append(A[i])
            i++
        else:
            temp.append(A[j])
            j++

    将剩余部分加入 temp

    拷贝回 A[l..r]

5. 核心机制(教学重点)

5.1 归并排序的本质

不是"直接排序",而是:

先拆到最小,再逐层合并

5.2 为什么一定能排序成功?

因为:

每一层都满足:

  • 子数组已经有序
  • 合并操作保持有序

5.3 合并过程本质

本质是:

两个指针的线性扫描

6. 示例

初始数组

text 复制代码
[6, 3, 8, 5]

拆分过程

text 复制代码
[6,3,8,5]
→ [6,3] [8,5]
→ [6] [3] [8] [5]

合并过程

text 复制代码
[6] + [3] → [3,6]
[8] + [5] → [5,8]

最终

text 复制代码
[3,6] + [5,8] → [3,5,6,8]

7. 时间复杂度

7.1 递推式

T(n)=2T(n/2)+O(n)\]\[ T(n) = 2T(n/2) + O(n) \]\[T(n)=2T(n/2)+O(n)

7.2 求解

T(n)=O(nlog⁡n)\]\[ T(n) = O(n \\log n) \]\[T(n)=O(nlogn)

7.3 关键理解

  • 每一层合并成本:(O(n))(O(n))(O(n))
  • 层数:(log⁡n)(\log n)(logn)

8. 空间复杂度

需要辅助数组:

O(n)\]\[ O(n) \]\[O(n)

9. 与快速排序对比(重点)

项目 快速排序 归并排序
核心操作 partition merge
时间复杂度 平均 (n log n) 始终 (n log n)
最坏情况 (n^2) (n log n)
空间 原地 额外 (n)
稳定性

10. 常见错误

❌ 错误1:认为 merge 很复杂

👉 本质只是"双指针"

❌ 错误2:忘记处理剩余部分

必须:

text 复制代码
while i ≤ mid
while j ≤ r

❌ 错误3:边界写错

特别是:

text 复制代码
mid + 1

11. 关键结论

  1. 归并排序核心是 merge
  2. 时间复杂度稳定 (nlogn)(n log n)(nlogn)
  3. 空间换时间
  4. 适用于大规模稳定排序

12. 最小教学总结

归并排序不是"在排",而是:
把问题拆小 → 再把有序结果合起来

相关推荐
EllinY4 小时前
CF2217E Definitely Larger 题解
c++·笔记·算法·构造
玖釉-8 小时前
下一个排列:从字典序到原地算法的完整推导
数据结构·c++·windows·算法
IronMurphy8 小时前
【算法五十】62. 不同路径
算法
影寂ldy8 小时前
C#一维数组
算法
枕星而眠8 小时前
数据结构八大排序详解(一):四大简单排序
c语言·数据结构·c++·后端
过期动态8 小时前
【LeetCode 热题 100】移动零
java·数据结构·算法·leetcode·职场和发展·rabbitmq
努力努力再努力wz9 小时前
【Qt入门系列】:按钮组件全解析:从 QAbstractButton 到快捷键事件、单选与复选机制
c语言·开发语言·数据结构·c++·git·qt·github
Dlrb12119 小时前
数据结构-栈
数据结构··内核栈·满栈空栈·增栈减栈
计算机安禾9 小时前
【算法分析与设计】第10篇:下界理论与NP完全性初步
大数据·人工智能·算法