什么时候应该在PriorityQueue上使用TreeMap,反之亦然?

时间:2010-08-19 18:12:05

标签: java priority-queue treemap

似乎他们都让你检索最小值,这是我对Prim算法所需要的,并强制我删除并重新插入一个键来更新它的值。使用一个优于另一个是否有任何优势,不仅仅是这个例子,但一般来说呢?

8 个答案:

答案 0 :(得分:26)

一般来说,使用堆来跟踪最小元素的工作量较少。

树更有条理,需要更多计算才能维护该组织。但是如果你需要访问任何键,而不仅仅是最小值,那么堆就不够了,并且树的额外开销是合理的。

答案 1 :(得分:6)

完全同意Erickson关于该优先级队列只给出最小/最大元素。

此外,由于优先级队列在维护数据总顺序方面不太强大,因此在某些特殊情况下具有优势。如果您想跟踪Tag数组中最大的M元素,则时间复杂度为N,空间复杂度为O(N*LogM)。但如果您在地图中执行此操作,则时间复杂度为O(M),空格为O(N*logN)。这是非常基本的,而在某些情况下我们必须使用优先级队列,例如O(N)只是一个常数,如10。

答案 2 :(得分:5)

我想指出有两点不同(这可能与Difference between PriorityQueue and TreeSet in Java?更相关,因为该问题被视为此问题的重复。)

(1)PriorityQueue可以有重复项,因为TreeSet不能有重复项。所以在Treeset中,如果你的比较器认为2个元素相等,那么TreeSet将只保留这两个元素中的一个并抛弃另一个元素。

(2)TreeSet迭代器以排序顺序遍历集合,而PriorityQueue迭代器不按排序顺序遍历。对于PriorityQueue如果要按排序顺序获取项目,则必须通过反复调用remove()来销毁队列。

我假设讨论仅限于Java对这些数据结构的实现。

答案 3 :(得分:3)

我可能迟到了这个答案,但仍然如此。

他们有自己的用例,其中任何一个都是明显的赢家。

例如:

1:https://leetcode.com/problems/my-calendar-i TreeMap是您正在查看的

2:https://leetcode.com/problems/top-k-frequent-words不需要键和值的开销。

所以我的答案是,查看用例,看看是否可以在没有键和值的情况下完成操作,如果可以,请转到PQueue,否则移至TreeMap。

答案 4 :(得分:2)

关于它的经验法则是:

TreeMap按顺序维护所有元素。 (如此直观地说,构建它需要时间)

PriorityQueue仅限隔离最小值或最大值。它更便宜但功能更低。

答案 5 :(得分:2)

这一切都取决于你想要达到的目标。在您选择其中一个之前,请考虑以下要点。

  1. PriorityQueue允许重复(即具有相同的优先级),而TreeMap不会。
  2. PriorityQueue的复杂度为O(n)(当增加其大小时),而TreeMap的复杂度为O(logn)(因为它基于红黑树)
  3. PriorityQueue基于Array,而TreeMap节点相互链接,因此包含PriorityQueue的方法需要O(n)时间,而TreeMap需要O(logn)时间。

答案 6 :(得分:1)

其中一个区别是remove(Object)和contains(Object)在基于普通堆的PriorityQueue(如Oracle)中是线性O(N),但是对于TreeSet / Map是O(log(N))。 / p>

因此,如果您有大量元素并执行大量删除(Object)或包含(Object),那么TreeSet / Map可能会更快。

答案 7 :(得分:0)

这取决于您如何实现优先级队列。根据Cormen的书第二版,最快的结果是斐波那契堆。