Java:优先级队列(或最小堆),删除任意节点

时间:2016-08-08 14:07:20

标签: java algorithm heap time-complexity priority-queue

我有一堆项目,我存储在最小堆(通过PriorityQueue),我需要有效删除任意项目。我知道在标准的小堆实现中,删除任意元素(假设你知道堆中该元素的位置)需要O(log n)时间,而查找位置是O (N)。所以,基本上,我需要保持一个单独的数据结构,它保存每个项目在堆中的位置。

我或多或少知道如何从头开始实现这一点。但我想知道是否有一种聪明的方法来利用/子类PriorityQueue(它有其他有用的功能)来实现这一目标。

更新:为了澄清,我需要PQ / Min-Heap提供的O(1)peek-min。

2 个答案:

答案 0 :(得分:3)

您是否考虑过使用TreeMap。它就像具有PriorityQueue类似功能的Map

TreeMap不支持O(1)进行删除,但是,它在O(logN)中执行删除操作。远胜于PriorityQueue对O(N)的支持。它还返回集合的头部(min或max元素,具体取决于比较器,就像PriorityQueue一样)。与此同时,它还返回集合的尾部(max或min)。 PriorityQueue不支持尾部功能,因此有时您最终会保留两个队列来同时跟踪头部和尾部。

定义

  • TreeMap
  

基于Red-Black树的NavigableMap实现。   该地图是根据其键的自然顺序排序的,   或在地图创建时由比较器提供,具体取决于   使用哪个构造函数。此实现可确保   log(n)containsKey,获取,放置和删除操作的时间成本。   算法是对Cormen,Leiserson和Rivest的算法的改编   算法简介。

  

红黑树是计算机中的一种自平衡二进制搜索树   科学。二叉树的每个节点都有一个额外的位,该位通常是   解释为节点的颜色(红色或黑色)。这些颜色位用于   确保树在插入和删除过程中保持大致平衡。

Reference to Red-Black Trees algorithm in Introduction to Algorithms

运行时间:

+----------------+-----------------+----------------------------------------------+
|   Operation    |     TreeMap     |                PriorityQueue                 |
+----------------+-----------------+----------------------------------------------+
| Insert(Object) | O(logN)[put]    | O(logN)[add]                                 |
| Get(Object)    | O(logN)[get]    | O(N)+ O(N)+O(logN) [contains + remove + add] |
| Delete(Object) | O(logN)[remove] | O(N)[remove]                                 |
| Head           |O(logN)[firstKey]| O(1)(peek)                                   |
| Tail           | O(logN)(lastKey)| -                                            |
+----------------+-----------------+----------------------------------------------+

答案 1 :(得分:1)

我还需要快速(log N)堆删除以进行超时处理。当队列中有数以万计的元素需要经常删除时,Java 的标准 PriorityQueue 就非常无效了。

这里是我创建的堆实现:fast-delete-heap

所以基本上它维护一个带有元素到堆索引的额外哈希映射,允许快速 O(log N) 删除。不过,它会带来插入速度较慢的代价。