☰
049自然两路合并排序
2026/9/29 19:40:42 网站建设 项目流程

自然两路合并排序 (Natural Two-Way Merge Sort)

049外部自然合并

故事:老图书馆员的智慧

在古老的图书馆深处,住着一位名叫艾德温的老馆员。他管理着成千上万的书籍,每天都要将它们按编号整理。年轻的学徒们总是用最笨的方法——一本一本地比较、交换,直到所有书排好序。

但艾德温有一个秘密武器。

"你们看,"他指着书架上已经部分有序的书,“这些书,虽然整体混乱,但仔细看,这里1-2-3-4是连续的,那里7-8-9也是有序的。为什么要破坏这些自然的秩序呢?”

艾德温的方法很简单:

  1. 识别自然段:他沿着书架走,每当发现编号开始下降时,就知道一个"自然段"(natural run)结束了
  2. 交替存放:把这些自然段交替放到两个推车上
  3. 合并:每次从两个推车各取一个段,像洗牌一样合并,放回书架

"如果数据本身就有序,"艾德温笑道,“我们一趟都不用走。”

算法原理

自然两路合并排序是外部排序的经典算法,源自 TAOCP 第3卷第5.4.1节。

核心思想

与传统归并排序强制从长度为1的段开始不同,自然合并排序利用数据中已存在的有序性:

  • 自然段(Natural Run):数组中连续的升序子序列
  • 初始分布时识别这些自然段,交替放入两条"磁带"
  • 反复合并,直到只剩一个有序段

算法流程

输入: [3, 1, 4, 1, 5, 9, 2, 6] 第0步 - 识别自然段: [3] [1,4] [1,5,9] [2,6] 交替分布: 磁带A: [3] [1,5,9] 磁带B: [1,4] [2,6] 第1步 - 合并: 合并 [3] 和 [1,4] → [1,3,4] 合并 [1,5,9] 和 [2,6] → [1,2,5,6,9] 交替分布: 磁带A: [1,3,4] 磁带B: [1,2,5,6,9] 第2步 - 合并: 合并 [1,3,4] 和 [1,2,5,6,9] → [1,1,2,3,4,5,6,9] 完成!

优势

情况传统归并自然归并
完全逆序log₂n 趟log₂n 趟
部分有序log₂n 趟更少趟数
完全有序log₂n 趟0 趟

复杂度分析

  • 时间复杂度: O(n log n) 最坏情况,O(n) 最好情况(已排序)
  • 空间复杂度: O(n) 需要额外存储空间
  • 趟数: 与初始 run 数相关,run 越少趟数越少

代码实现要点

  1. 磁带模拟:用数组+位置指针模拟磁带读写
  2. Run 识别:遍历数组,遇到下降即为一个 run 结束
  3. 合并策略:每趟合并两个磁带上的 runs,交替输出

历史意义

自然合并排序诞生于磁带机时代,当时外部存储访问成本极高。利用数据的自然有序性可以显著减少磁带读写次数,这在当时意味着节省大量时间和金钱。

即使在今天的内存排序中,识别自然 runs 的思想仍然有价值——TimSort(Python的排序算法)就采用了类似策略。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询