Algorithm 我们是否有优先级队列,它支持与其他操作一样复杂的删除操作?

Algorithm 我们是否有优先级队列,它支持与其他操作一样复杂的删除操作?,algorithm,data-structures,priority-queue,Algorithm,Data Structures,Priority Queue,优先级队列以从集合中检索max或min元素而闻名。 优先级队列上的两个常见操作是Insert和DeleteMin/DeleteMax。 我们是否有支持删除(x)的优先级队列? 删除(x)的含义是从优先级队列中删除项目x 最简单的方法是找到项目x并将其删除,但这需要线性时间。我在寻找更好的算法 某些类型的优先级队列确实支持此操作。通常,您可以通过让delete(x)操作接受x作为数据结构内的指针来完成此操作,该指针指示应删除的元素。例如,在二项式堆或斐波那契堆中,每个元素都存储为林中的一个节点,i

优先级队列以从集合中检索max或min元素而闻名。 优先级队列上的两个常见操作是InsertDeleteMin/DeleteMax。 我们是否有支持删除(x)的优先级队列? 删除(x)的含义是从优先级队列中删除项目x


最简单的方法是找到项目x并将其删除,但这需要线性时间。我在寻找更好的算法

某些类型的优先级队列确实支持此操作。通常,您可以通过让delete(x)操作接受x作为数据结构内的指针来完成此操作,该指针指示应删除的元素。例如,在二项式堆或斐波那契堆中,每个元素都存储为林中的一个节点,insert(x)操作可能会返回一个指向保存元素x的节点的指针,然后delete(x)可以跟随提供的指针快速找到要删除的元素

在以这种方式支持delete(x)的大多数优先级队列(斐波那契堆、二项式堆、配对堆等)中,delete(x)的复杂性与delete min的复杂性相同,但这取决于数据结构的特定实现


希望这有帮助

任何平衡的二叉树结构都可以在INSERT和Delete下存储排序序列,而不仅仅是最小元素,并且可以获得与二进制堆相似的渐近时间界限。

如果优先级队列库不支持
Delete(x)
函数,我会使用一种欺骗方法

我将使用两个优先级队列,
ORI
DELETED
ORI
将是我的原始优先级队列,
DELETED
用作标记删除哪些元素的池

要添加元素,只需将其添加到
ORI
。 要删除元素,只需将其添加到
DELETED

当您查询优先级队列的顶部(如Min/Max)时,神奇的效果就出现了:

1)
ORI
的顶部等于
DELETED
时,删除两个优先级队列的顶部(使用DeleteMin/DeleteMax)

2) 一旦两个优先级队列的顶部不相等,
ORI
的顶部将是您要查找的实际“顶部”

这在一定程度上延迟了“删除”,直到要删除的元素位于优先级队列的顶部。这是因为如果标记为要删除的元素不是优先级队列的顶部,则优先级队列的顶部不会更改

然而,这种“欺骗”的缺点是需要更多的内存来存储标记为“删除”的元素

删除函数的复杂性最终被武装化为O(logn)

编辑: 这样,您就不必实现自己的数据结构:P
我一直在使用C++中的STL优先级队列在编程竞赛中使用这个技术。

可以从O(log n)中的斐波那契堆中删除。谢谢。但大多数情况下,用户可能不知道元素的指针,在这种情况下如何处理,有什么建议吗?@r但您可以在优先级队列内部执行类似的操作。存储从元素到它们在队列中的“位置”的哈希表映射(对于“位置”的某些定义),并使该哈希表与数据结构的其余部分保持同步。然后,您可以通过在哈希表中查找x并从中查找要删除的元素来实现**删除**(x)。谢谢,是的,保留哈希表是有意义的。您还可以使用此方案用“排序与您删除的内容类似的墓碑”覆盖优先级队列中的内容并修改extract min以跳过墓碑。这需要进行摊销分析——从空队列开始的任何操作序列都可以得到所需的时间范围。这是一个有趣的想法,但它使
Peek()
成为一个O(logn)操作,而通常它是一个O(1)操作。它有点像O(1)一样被武装起来,因为O(logn)可以归因于delete。(例如,您可以连续重复调用Peek(),并且不会发生进一步的删除->O(1))