因此,假设我有一个优先级为N项的优先级队列,其中N为数千,使用binary heap实现的优先级队列。我了解EXTRACT-MIN
和INSERT
原语(请参阅使用-MAX
而不是-MIN
的{{3}})。
但是DELETE
和DECREASE-KEY
似乎都要求优先级队列能够在给定项目本身的情况下在堆中找到项目的索引(或者,该索引需要由优先级队列,但这似乎是一个抽象违规)....这看起来像一个疏忽。有没有办法有效地做到这一点,而无需在堆顶部添加哈希表?
答案 0 :(得分:1)
是的,我认为这里的重点是,对于优先级队列的实现,您可以使用二进制堆,其API为其HEAP-INCREASE-KEY(A,i,key)获取索引(i),但是可以允许优先级队列的接口采用任意密钥。您可以自由地使用优先级队列封装key->索引映射的详细信息。如果你需要你的PQ-INCREASE-KEY(A,旧的,新的)在O(log n)中工作,那么你最好有一个O(log n)或更好的索引查找键来保持最新状态。这可能是哈希表或其他快速查找结构。
所以,回答你的问题:我认为数据结构不可避免地要增加一些方式。
答案 1 :(得分:1)
FWIW,如果有人仍在寻找类似的东西 - 我最近偶然实现了一个 Indexed 优先级队列的实现,同时做了一个关于算法的Coursera课程。
基本要点是使用2个数组合并反向查找,以支持OP所述的操作。
答案 2 :(得分:0)
“但DELETE和DECREASE-KEY似乎都要求优先级队列能够在给定项目本身的情况下在堆中找到项目的索引” - 从代码中可以清楚地看出,这些方法中至少有一些使用了索引到堆而不是项的优先级。显然,我是HEAP-INCREASE-KEY的索引:
HEAP-INCREASE-KEY(A, i, key)
if key < A[i]
then error 'new key is smaller than current key"
A[i] <-- key
...
因此,如果是API,请使用它。
答案 3 :(得分:0)
我修改了我的节点类以添加一个heapIndex成员。在插入,删除,减少等期间交换节点时,这由堆维护。
这破坏了封装(我的节点现在绑定到堆),但它运行得很快,这在我的情况下更为重要。
答案 4 :(得分:0)
一种方法是将堆分成一边的元素,另一边分割组织。
要获得完整功能,您需要两个关系: a)给定堆位置(例如Root),找到坐在那里的元素。 b)给定一个元素,找到它的堆位置。
第二个非常简单:添加一个值“location”(很可能是基于数组的堆中的索引),每次在堆中移动元素时都会更新它。
第一个也很简单:您只需保留一堆指向Elements(或数组indeces)的指针,而不是存储Elements。现在,给定一个位置(例如Root),您可以通过解除引用(或访问向量)找到位于那里的元素。
答案 5 :(得分:0)
但DELETE和DECREASE-KEY似乎都要求优先级队列能够在给定项目本身的情况下在堆中找到项目的索引
实际上,那不是真的。您可以通过使用前导和后继指针在未编制索引的图形,链接列表和“传统”搜索树中实现这些操作。