Priority Queue以从集合中检索max或min元素而闻名。 优先级队列上的两个常见操作是插入和 DeleteMin / DeleteMax 。 我们是否有支持删除(x)的优先级队列? 删除(x)的含义是两个从优先级队列中删除项目x 。
这种天真的方法是找到项目x并将其删除,但这需要线性时间。我正在寻找一些更好的算法。
答案 0 :(得分:6)
某些类型的优先级队列确实支持此操作。通常,您可以通过 delete (x)操作接受x作为数据结构内的指针来指示应删除哪个元素。例如,在二进制堆或Fibonacci堆中,每个元素都存储为林中的节点, insert(x)操作可能会将指针传回指向包含元素x的节点,并且删除(x)然后可以按照提供的指针快速找到要删除的元素。
在支持删除(x)这种方式的大多数优先级队列中(Fibonacci堆,二项式堆,配对堆等),删除(x)的复杂性与 delete-min 的复杂性相同,但这取决于数据结构的特定实现。
希望这有帮助!
答案 1 :(得分:1)
任何平衡的二叉树结构都可以在插入和删除下存储排序的序列,而不仅仅是最小元素,并且一个类似于二进制堆的渐近时间边界。
答案 2 :(得分:1)
如果优先级队列库不支持Delete(x)
函数,我会使用作弊方式。
我将使用2个优先级队列,ORI
和DELETED
。
ORI
将是我的原始优先级队列,DELETED
用作标记要删除哪些元素的池。
要添加元素,只需将其添加到ORI
即可。
要删除元素,只需将其添加到DELETED
。
当您查询优先级队列的顶部(例如最小/最大)时,会出现魔力:
1) ORI
的顶部等于DELETED
,删除两个优先级队列的顶部(使用DeleteMin / DeleteMax)
2)一旦两个优先级队列的顶部不相等,ORI
的顶部将是您正在寻找的实际“顶部”。
这有点延迟'删除',直到要删除的元素位于优先级队列的顶部。这是有效的,因为如果标记为要删除的元素不是优先级队列的顶部,则优先级队列的顶部不会更改。
然而,这种“欺骗”的缺点是需要更多的内存来存储标记为“删除”的元素。
删除功能的复杂性最终被标记为O(log N)
编辑: 这样,您就不必实现自己的数据结构:P 我一直在使用STL优先级队列在C ++编程竞赛中使用这种技术。