【问题标题】:Priority queue O(1) insertion and removal优先队列 O(1) 插入和移除
【发布时间】:2013-03-26 20:04:26
【问题描述】:

优先级队列是否可以同时进行 O(1) 的插入和删除?

可以使用堆来实现优先级队列,并查看斐波那契堆的运行时间,似乎每次删除都无法获得比 O(logN) 更好的运行时间。

我正在尝试实现一个数据结构,其中给定 N 个项目,我将有一半在最大优先级队列中,一半在最小优先级队列中。然后我将依次删除所有 N 项。

我可以在 O(N) 时间内插入所有 N 个元素,但删除所有 N 个元素需要 O(N*logN),所以我想知道另一种方法是否更合适。

【问题讨论】:

  • 如果您可以进行 O(1) 插入和 O(1) 删除,您可以使用它在 O(n) 时间内对列表进行排序。在一般情况下,您不应该这样做。所以这强烈反对这种可能性。
  • @harold 详细地说,有一个数学证明,N 个元素的比较排序必须进行与N log N 成比例的比较次数。因此,除非您在经过同行评审的十年前的结果中发现致命缺陷,否则就是这样。 但是,对于特定类型的数据,例如整数,您可以做得更好,因为您可以做的不仅仅是比较(例如,将它们分桶或将它们用作随机访问的索引收藏)。可以想象,这同样适用于优先级队列。但说实话,我从来没有听说过这样的数据结构。
  • @harold- 你真的应该把它作为答案发布——我本来打算这么做的,但我会因为窃取你的声望点而感到难过。 :-)

标签: data-structures


【解决方案1】:

如果您可以构造一个具有 O(1) 插入和 O(1) 删除的优先级队列,则可以使用它在 O(n) 时间内对包含 n 个项目的列表进行排序。正如this answer 中所解释的,在一般情况下,您不能在 O(n) 中进行排序,因此如果不对输入。

例如,可以构造一个具有 O(1) 插入和 O(k)(k 是可以插入的最大元素)移除的优先级队列。保留一个包含 k 个链表的表。插入x 只是将一个项目添加到xth 列表的前面。删除必须扫描表以找到第一个非空列表(然后删除列表的第一项并返回该列表的索引)。只有 k 个列表,因此删除需要 O(k) 时间。如果 k 是一个常数,那么移除时间为 O(1)。

在实践中,使用计数表会更好。除非您使用摊销分析(这就是我在上一段中没有使用它的原因),否则递增可变长度整数不是恒定时间,但实际上您无论如何都不需要可变长度计数。此外,在实践中,即使 k 是常数,它也会对较大的 k 不利 - 您会很快耗尽内存,并且扫描第一个非零元素可能需要一段时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-13
    相关资源
    最近更新 更多