关于java:使用O(log n)删除任意节点的优先级队列(或最小堆)

Priority queue (or min-heap) with O(log n) deletion of arbitrary node

我有一堆要存储在最小堆中的项目(通过PriorityQueue),我需要有效地删除任意项目。我知道在标准的最小堆实现中,删除任意元素(假设您知道该元素在堆中的位置)将花费O(log n)时间,而找到位置是O(n)。因此,基本上,我需要保留一个单独的数据结构,该数据结构保存每个项目在堆中的位置。

我或多或少知道如何从头开始实现此功能,但是我想知道是否存在一种巧妙的方法来利用/子类PriorityQueue(具有其他有用的功能)来完成此任务。

为澄清起见,我需要PQ / Min-Heap提供的O(1)peek-min。


您是否考虑过使用TreeMap。它就像具有地图功能的PriorityQueue。

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

  • 头元素-> TreeMap#firstKey
  • 尾元素-> TreeMap#lastKey

定义

  • 树状图

A Red-Black tree based NavigableMap implementation.
The map is sorted according to the natural ordering of its keys,
or by a Comparator provided at map creation time, depending on
which constructor is used.This implementation provides guaranteed
log(n) time cost for the containsKey, get, put and remove operations.
Algorithms are adaptations of those in Cormen, Leiserson, and Rivest's
Introduction to Algorithms.

  • 红黑树

A red–black tree is a kind of self-balancing binary search tree in computer
science. Each node of the binary tree has an extra bit, and that bit is often
interpreted as the color (red or black) of the node. These color bits are used to
ensure the tree remains approximately balanced during insertions and deletions.

算法简介中对Red-Black Trees算法的引用

运行时间:

1
2
3
4
5
6
7
8
9
+----------------+-----------------+----------------------------------------------+
|   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)| -                                            |
+----------------+-----------------+----------------------------------------------+

我还需要快速删除(日志N)堆以进行超时处理。当队列中有成千上万的元素需要经常删除时,Java的标准PriorityQueue效率很低。

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

因此,基本上,它使用元素到堆索引维护了一个额外的哈希映射,该索引允许快速删除O(log N)。但是,这会带来插入速度较慢的代价。