ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

049自然两路合并排序

049自然两路合并排序 自然两路合并排序 (Natural Two-Way Merge Sort)049外部自然合并故事老图书馆员的智慧在古老的图书馆深处住着一位名叫艾德温的老馆员。他管理着成千上万的书籍每天都要将它们按编号整理。年轻的学徒们总是用最笨的方法——一本一本地比较、交换直到所有书排好序。但艾德温有一个秘密武器。你们看他指着书架上已经部分有序的书“这些书虽然整体混乱但仔细看这里1-2-3-4是连续的那里7-8-9也是有序的。为什么要破坏这些自然的秩序呢”艾德温的方法很简单识别自然段他沿着书架走每当发现编号开始下降时就知道一个自然段natural run结束了交替存放把这些自然段交替放到两个推车上合并每次从两个推车各取一个段像洗牌一样合并放回书架如果数据本身就有序艾德温笑道“我们一趟都不用走。”算法原理自然两路合并排序是外部排序的经典算法源自 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 越少趟数越少代码实现要点磁带模拟用数组位置指针模拟磁带读写Run 识别遍历数组遇到下降即为一个 run 结束合并策略每趟合并两个磁带上的 runs交替输出历史意义自然合并排序诞生于磁带机时代当时外部存储访问成本极高。利用数据的自然有序性可以显著减少磁带读写次数这在当时意味着节省大量时间和金钱。即使在今天的内存排序中识别自然 runs 的思想仍然有价值——TimSortPython的排序算法就采用了类似策略。
返回列表