为什么Java的Priority Queue缺少Change Priority方法?

时间:2015-06-23 10:45:19

标签: java priority-queue decrease-key

我想知道为什么Java的Priority Queue不支持ChangePriority。我已经阅读了某处(没有详细信息),删除ChangePriority允​​许使用更高效的实现,但不知道它是如何可能的 - 二进制堆似乎非常简单/高效的数据结构 - 看不到任何改进的空间。另一个线索可能是它可能需要一个尴尬的接口来向PQ指示哪个元素(可能是堆中的位置)改变了它的优先级,但我仍然是Java的新手得出结论。

编辑:为什么这可能不是一个毫无意义的问题?如果您不熟悉Java(特别是来自C / C ++背景),您会开始怀疑所有指针的位置,或者如何在Java等中实现Dijkstra。

根据我的理解,第一个问题已被多次回答,第二个问题是一个简单的答案。人们可以期待在像Java这样的语言中,您可以随时使用所有常用的编程工具,开箱即用,封装在一个漂亮的类包装器中。但突然之间你必须自己实现一个带有reduce键方法的PQ,这可能是一个比较简单的事情,在Java中然后在C / C ++中。 在这个问题中,我不是在问如何实现Dijkstra(这在其他一些线程中得​​到了很好的回答)。 PQ的许多应用仍然可以在没有减少键/ prio方法的情况下进行分类,例如。如果有更多的优先级更新,那么PQ中的项目。在Dijkstra,最多有五个

因此人们可能会认为Java的PQ缺乏变更优先级存在一些严重的原因。无论Java的PQ接口是什么,原因都可能很有趣。

2 个答案:

答案 0 :(得分:1)

我怀疑设计选择是因为它是Queue。队列的基本操作是入队和出队。 Priority Queue的不同之处在于,作为入队操作的一部分,它允许元素优先于其他元素。大多数Queue实现不允许在元素放入后操纵元素,尽管有些提供peek功能。所以我们的数据类型是一个队列,我不是真的"假设"混淆内部安排,我也不应该关心。如果我使用队列,我基本上想要先入先出行为。 Queue

话虽如此,你怎么能实现你想要的行为?我建议TreeMap。它为您提供类似队列的功能,我可以通过firstKey()lastKey()获取第一个或最后一个元素,同时仍然通过我自己的Comparator接口提供人工排序以及访问条目通过Key,尽管您的Key实施必须同时提供唯一标识符及其排序顺序。

答案 1 :(得分:0)

虽然我无法确定为什么没有为PriorityQueue公开更改优先级方法,但可以观察到当PriorityQueue中对象的优先级发生变化时,您可以简单地删除重新插入对象。

PriorityQueue的这种行为存在,因为无论何时在队列中插入新对象,它都会被放置在适当的位置(基于对象的比较器)。这很有效,因为每次从队列中取出某些东西时,不需要重新计算来查找具有最小/最大优先级的元素。这带来了一旦将对象的优先级插入队列后就无法更改的限制。

删除和重新插入对象确实比较慢,可以看出代码的整体运行时复杂性仍然保持不变。也就是说,如果您有兴趣查看优先级队列的自定义Java实现,这可以是一个很好的起点 - http://algs4.cs.princeton.edu/24pq/IndexMinPQ.java.html