在浏览标准库的不太知名的部分时,我偶然发现了std :: sort_heap。 但我不明白为什么它存在,因为有一个名为std :: sort的自由函数。
另请注意,复杂性是相同的。
所以我的问题是:sort_heap存在的理由是什么。
答案 0 :(得分:10)
sort_heap
假设输入已经是heap的形式。这意味着它理论上可以比std::sort
更有效地工作,因为对输入的顺序有一些限制(不像std::sort
,它必须适用于所有输入)。
正如评论中所提到的,值得注意的是,这些性能优势无法确保,显然取决于输入数据,因此如果性能很重要,那么实际上无法进行性能分析。
答案 1 :(得分:4)
在数据已经具有堆属性的情况下,有一个明显的排序算法不适用于没有该属性的数据 - 重复删除堆的最大元素并恢复堆属性。这就是heapsort的工作原理(首先堆积数据,然后使用heap属性对其进行排序)。
所以,假设你有一个堆,你想要它排序。您可以调用std::sort
,但std::sort_heap
存在以暗示使用此算法[*]。至少可以为程序员提供潜在提高排序性能的方法。实际上是否更快是另一回事。
观察std:sort
被允许作为一个堆被实现,尽管我怀疑它是永远的。
如果sort_heap
不可用,世界将继续存在,因为还有另一种方法可以获得相同的行为:在原始堆的较小和较小的初始段上重复调用pop_heap
。因此,如果它让您感到麻烦,请将其视为纯粹的便利功能。但是,有可能有优化而不是可以应用sort_heap
比这更好。
可能影响C ++ 03作者思想的历史记录:在STL的SGI版本中,sort
被定义为使用introsort,而partial_sort
被定义为使用heapsort 。我不认为这正是将它包含在标准中的理由:它也是一个“明显”的函数,包括堆算法。
[*]这是一个非常强烈的暗示,因为sort_heap
的复杂性要求是“最多N log N比较”,而不是“O(N log N)比较”。因此,实现不能sort_heap
调用sort
,除非它知道当输入数据具有堆属性时,它自己的sort
实现最多执行那么多的比较。
答案 2 :(得分:2)
复杂度保证实际上并不相同。
std :: sort需要堆栈上O(log N)个内存。 std :: sort_heap需要O(1)数量的堆栈。 这在堆栈空间受限的环境中(例如在嵌入式应用程序中(即在微控制器上运行))有很大的不同。即使在数千个元素数组上调用std :: sort也可能导致堆栈溢出。
顺便说一句,在嵌入式环境中,内部存储通常是SRAM,因此您不必担心在快速排序/内向排序获得性能优势的缓存位置。
因此,在微控制器环境中,建议写
std::make_heap(data.begin(), data.end());
std::sort_heap(data.begin(), data.end());
代替
std::sort(data.begin(), data.end());
答案 3 :(得分:0)
取自:http://www.sgi.com/tech/stl/sort_heap.html
sort_heap将堆[1] [first,last]转换为排序范围。注意,这不是稳定的> sort:不保证保留等效元素的相对顺序。
std :: sort可能会在最坏的情况下根据实现提供O(N ^ 2)复杂度,并处理未排序的数据集。 std :: sort_heap在堆上工作,总是给你O(nlogn)