【问题标题】:Using heap for big disk sorts使用堆进行大磁盘排序
【发布时间】:2025-12-11 02:15:01
【问题描述】:

在 Python 官方文档here 中提到:

堆在大磁盘排序中也非常有用。你们很可能都是 知道大排序意味着产生“运行”(预先排序 序列,其大小通常与 CPU 内存量有关), 然后是这些运行的合并通行证,合并通常是 组织得非常巧妙。
初始阶段非常重要 sort 产生尽可能长的运行。比赛是个好方法 实现这一目标。如果,使用所有可用的内存来保存一个 锦标赛,您替换和过滤恰好适合 当前运行,您将产生两倍于当前运行大小的运行 随机输入的内存,对于模糊排序的输入更好。

此外,如果您输出磁盘上的第 0 个项目并获得一个输入 可能不适合当前的锦标赛(因为值“胜出” 最后一个输出值),它不能放入堆中,所以 堆减少。释放的内存可以巧妙地重用 立即用于逐步构建第二个堆,该堆的增长速度为 与第一堆融化的速率完全相同。
当第一个堆 完全消失,您切换堆并开始新的运行。聪明和 很有效!

我知道一种称为External sorting 的算法,其中我们:

  1. 将输入分解成更小的块。
  2. 单独对所有块进行排序,并将它们一一写回磁盘。
  3. 创建一个堆并在所有已排序的块之间进行 k 路合并。

我完全理解*上描述的外部排序,但是当他们说时我无法理解作者:

如果使用所有可用的内存来举办锦标赛,您替换 并过滤恰好适合当前运行的项目,您将产生 运行是随机输入内存大小的两倍,而且很多 更适合模糊排序的输入。

和:

此外,如果您输出磁盘上的第 0 个项目并获得一个输入 可能不适合当前的锦标赛(因为值“胜出” 最后一个输出值),它不能放入堆中,所以 堆减少。

这是什么堆熔化

【问题讨论】:

    标签: python algorithm sorting heap external-sorting


    【解决方案1】:

    堆熔化不是一回事。这只是作者用来表示堆变小以拉出最小的项目的词。

    他所说的想法是对外部排序的“将输入分成块并对块进行排序”部分的巧妙替代。它产生更大的排序块。

    这个想法是,您首先将最大的块读入内存并将其排列到堆中,然后在读取新元素时开始从堆中写出最小的元素。

    当你读入一个小于你已经写出的元素的元素时,它不能进入​​当前块(它会破坏排序),所以你记住它以备下一个块。可以将不小于您写出的最后一个元素的元素插入堆中。它们会将其放入当前块中,使当前块变大。

    最终你的堆会是空的。至此,你已经完成了当前的块——堆起你记得的所有元素并开始写出下一个块。

    【讨论】: