似乎他们都让你检索最小值,这是我对Prim算法所需要的,并强制我删除并重新插入一个键来更新它的值。使用一个优于另一个是否有任何优势,不仅仅是这个例子,但一般来说呢?
答案 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)
这一切都取决于你想要达到的目标。在您选择其中一个之前,请考虑以下要点。
答案 6 :(得分:1)
其中一个区别是remove(Object)和contains(Object)在基于普通堆的PriorityQueue(如Oracle)中是线性O(N),但是对于TreeSet / Map是O(log(N))。 / p>
因此,如果您有大量元素并执行大量删除(Object)或包含(Object),那么TreeSet / Map可能会更快。
答案 7 :(得分:0)
这取决于您如何实现优先级队列。根据Cormen的书第二版,最快的结果是斐波那契堆。