Skip to content

算法Algorithm

归并排序

施工中 · 内容逐步修订

Merge sort

递归排序两半并线性合并的稳定比较排序算法。

形式陈述 ​

归并排序实现比较排序:输入带可比较键的有限序列,输出包含相同元素重数的非降序列。本页采用自顶向下的稳定版本。长度 n≤1 时原样返回;否则按原次序分成长度 ⌊n/2⌋ 与 ⌈n/2⌉ 的两段,递归排序,再合并。

合并维护两段各自的首个未输出位置。两边都非空时,输出键较小的一项并推进该边;键相等时优先输出左段的项。一边耗尽后,把另一边剩余项依次接上。每次输出都移走一个未输出元素,因此合并会终止,输出中每条原记录恰好出现一次。

在单次比较、读取和搬移元素为常数成本的数组模型中,标准实现的运行时间满足递推关系

T(n)=T(⌊n/2⌋)+T(⌈n/2⌉)+Θ(n)(n≥2),

基例为 T(0),T(1)=Θ(1),故 T(n)=Θ(nlog⁡n)。共用一个辅助数组需要 Θ(n) 额外元素空间,递归栈另为 O(log⁡n)。

直觉

这是分治法中“先解决小问题,再组合答案”的典型例子。两边已经有序,所以全体剩余项中的最小者必在两个首项之一;不必重新搜索整段,也不必撤回已经输出的项。

把合并展开成层,每个内部层总共处理 O(n) 项,层数为 O(log⁡n)。这个图像解释时间界,但正确性还来自每次合并确实维护了次序和元素重数,两项缺一不可。

递归拆分与稳定双路归并
例子与边界

合并为什么正确且稳定 ​

排序 [4,1,3,2] 时,两段递归结果为 [1,4] 与 [2,3]。比较首项依次输出 1,2,3,再接上 4。合并的循环不变式是:输出前缀已经有序,且每个已输出键不大于两侧任一剩余键;已输出与未输出记录合在一起,仍是原两段的全部记录及其重数。

每次选择较小首项保持这三点。循环结束后,两侧已全部输出,于是结果有序且没有丢失重复记录。递归按更小长度终止,结合基例便证明整体排序正确。

若相等键附带身份,例如输入 [2a,1,2b,0],左、右半中的两个 2 分别保留身份。最后合并在平局时先取 2a,保住它早于 2b 的原次序。各半内部由递归保持稳定,跨半的平局由左优先保持稳定;若平局改取右侧,稳定性就可能失败。

表示和变体改变成本 ​

链表可以通过重接节点合并,不需要线性大小的辅助元素数组;普通递归版本仍需调用栈。自底向上的链表归并可以进一步避免递归栈,但那是另一份执行方案,不能只从“用了链表”推出全部额外空间为常数。

标准数组版本需要线性辅助空间。更复杂的原地归并算法确实存在,不能反过来把它们的空间界安到本页方案上。自然归并排序会利用已经有序的连续段,某些输入因此更快;本页递推描述的是固定近半分割、逐层合并的版本。

Powersort先保留非降段与反转后的严格下降段,再按相邻原段中点的二进制分歧选择归并次序。对于段长比例pᵢ,归并体积距离最优有序树小于2n;该体积由记录参与归并的次数决定。galloping归并则改变一次双路归并内部的比较方式,用指数探测批量越过长前缀,两项改动分别影响调度与比较。

推论与应用

最坏 O(nlog⁡n) 的比较数达到一般比较排序下界的渐近量级。稳定性则是另一项保证,由相等键的合并规则给出,不能从时间最优性推出。

归并适合顺序扫描。外存排序在内存中缓冲多段并作多路归并,用更少轮次控制块传输;Funnel Sort再用递归缓冲结构取得缓存无关界。它们与本页共享合并思想,但需分别给出内存容量、块大小和 I/O 成本。

归并过程也能计数逆序对:当右首项严格小于左首项时,它还小于左段全部剩余项,因而一次加入左段剩余项数。相等时先取左边,避免把相等键误计为逆序。并行实现则还要选择并行合并方法,不能只把两个递归调用同时启动,就宣称所有合并成本也被平分。

参考资料
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022,§2.3:归并排序、正确性与递推分析。
  • Donald E. Knuth, The Art of Computer Programming, Vol. 3: Sorting and Searching, 2nd ed., Addison-Wesley, 1998,§5.2.4:归并排序及其变体。
关系图谱16 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系