为什么大多数语言都提供最小堆而不是最大堆实现?


19

我只是注意到了什么,我想知道是否有任何原因。除了C ++(std :: priority_queue是最大堆)之外,我不知道其他提供最大堆的语言。

Python的heapq模块在列表顶部实现了一个二进制min-heap。

Java的库包含一个PriorityQueue类,该类实现了一个最小优先级队列。

Go的库包含一个container / heap模块,该模块在任何兼容的数据结构之上实现了min-heap。

苹果公司的Core Foundation框架包含一个CFBinaryHeap结构,该结构实现了最小堆。

我发现最大堆比最小堆更直观,而且从技术上讲,我认为实现差异只是更改比较运算符的问题。有什么真正的原因吗?大多数应用程序需要最小而不是最大堆吗?提前致谢


他们不是一回事吗?我投票结束辩论。

2
就在几天前,我在C ++中需要一个最小堆,并且对priority_queue默认为最大堆感到有些恼火。这迫使我在自定义类上定义了运算符>,该类已经具有运算符<。使用图形时,通常需要优先考虑最短的边,因此需要最小的堆。
LaC 2011年

2
@LaC:可以使用std::not2(std::less<T>())

Answers:


9

正如其他人所观察到的,如果堆接受一个比较器,那么获得一个或另一个行为并不难。但是,快速浏览一下Google Code,这表明min-heap在实际代码中更为普遍,因为两个应用程序一次又一次出现。

  • Dijkstra / A * /许多其他最短路径算法(因为部分路径会变长)。

  • 事件模拟(因为时间过去了)。

另外,我认为,由于默认排序会返回从小到大的项目,因此默认堆也应如此。


2
我通常使用C ++进行编程,而想知道相反的情况:为什么C ++不实现最小堆?如您所说,大多数算法都使用最小堆。
马丁·菲克斯曼(MartínFixman)2011年

5

这只是一个品味问题。我认为没有任何具体原因。就像有些人喜欢表达优化问题(例如降低成本),而其他人喜欢表达最大化利润。


3

我知道的大多数语言都允许传递参数来决定它应该是最小堆还是最大堆。因此,默认值有些随意。我猜对于大多数语言来说,定义默认运算符是一个一致性问题。对于stl中的C ++,默认值std::less导致最小堆。

std::less所有地方使用默认值的一致性意味着仅在使用任何类型的数据结构时才需要执行此比较,并且在设计类时不必决定以后要使用哪种数据结构。我猜想其他语言也一样,唯一的不同是比较标准是比较标准。


3
我认为没有这种联系。您可以使用<或>实现任何一种堆。确实,std :: less是STL中的默认设置,但是它们实现的是最大堆而不是最小堆。
LaC 2011年

1

索引值基本上是一个任意数字。如果您认为数字代表优先级,而数字越大则优先级越高,那么最大堆是有意义的。但是,如果数字表示例如概念性面包店编号(“ Take a number”),则最小堆更有意义。

您始终可以采用索引的1的补码从一种转换为另一种。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.