【发布时间】:2025-11-22 12:10:02
【问题描述】:
在研究排序算法时,称为堆排序,用于外部排序。 当我们处理外部存储时,我无法弄清楚它在排序技术方面有何不同?或者,堆排序唯一被认为对外部排序有用的东西是什么?
有人能解释一下吗?
【问题讨论】:
-
这不是堆排序。这就是基于堆的 k 路合并的合并排序。
标签: sorting heapsort binary-heap external-sorting
在研究排序算法时,称为堆排序,用于外部排序。 当我们处理外部存储时,我无法弄清楚它在排序技术方面有何不同?或者,堆排序唯一被认为对外部排序有用的东西是什么?
有人能解释一下吗?
【问题讨论】:
标签: sorting heapsort binary-heap external-sorting
排序的外部部分是k-way归并排序。外部媒体(如硬盘驱动器)上的数据块或数据文件一次重复合并“k”个,直到生成单个排序文件。
最小堆是实现 k 路合并内部部分的常用方法。
创建数据块或数据文件的初始过程几乎可以是任何内部排序,如果需要稳定性,则可以是稳定的。在对记录进行排序的情况下,合并排序可用于对指向记录的指针数组进行排序,这减少了空间需求,因为只有指针数组需要第二个数组,而不是记录的第二个数组。应该注意的是,对指针进行排序可能比对记录进行排序要慢,因为通过指针排序最终会随机访问记录进行比较,这对缓存不友好。
用于大型文本文件的 Gnu 排序是外部排序的一个示例。它一次读取一个“块”行,创建指向行的指针,并对指针使用合并排序,然后为每个排序的块创建一个临时文件。然后,它对临时文件进行 16 路(默认为 16 路)合并,直到到达最终合并步骤,最终合并到指定的输出文件。
来源链接。这是一个很大的程序,部分原因是它有很多选择。
http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/sort.c
【讨论】:
我们以the Linux kernel code为例:
此函数对给定数组进行堆排序。平均和最坏情况下的排序时间都是 O(n log n)。虽然 qsort 平均快 20% 左右,但它存在可利用的 O(n*n) 最坏情况行为和额外的内存需求,使其不太适合内核使用。
来自Wikipedia:
堆排序还与具有相同时间界限的合并排序竞争。合并排序需要 Ω(n) 辅助空间,但堆排序只需要一个常数。堆排序通常在数据缓存小或慢的机器上运行得更快,并且不需要太多的外部内存。
【讨论】:
不是
堆排序最适合在外部排序中创建初始运行,
但是使用堆来创建初始运行会导致预期初始运行长度是堆大小的两倍(对于统一分配密钥),因此,初始运行次数是任何方法的一半,对每批记录进行排序并将其写入一次运行(使用相同数量的 RAM)。
通过双向合并,一半的初始运行可以节省整个传递。使用高级合并方案,高度(运行次数合并为一次),甚至通过次数(比率数据/RAM 大小),这将失去影响。
【讨论】: