使用集合与优先级队列实现的二进制堆的渐近复杂性

时间:2016-12-18 01:39:47

标签: java algorithm asymptotic-complexity amortized-analysis

我正在审查决赛并且偶然发现了以下问题:

二进制堆默认情况下具有优先级队列语义:如果我们插入一些元素n次,我们需要在它“消失”之前将其删除n次。想象一下,你想要用set语义实现二进制堆。在这种情况下插入和移除操作的速度有多快?

(a)插入:O(n)删除:O(logn)

(b)insert:O(log n)remove:O(n)

(c)insert:O(log n)remove:O(log n)

(d)插入:O(1)去除:O(n2)

(e)以上都不是。

要插入使用优先级队列语义实现的堆,它将是O(logn),因此将删除。但是对于集合,插入和删除取决于集合本身的许多因素。您认为答案应该是什么?

2 个答案:

答案 0 :(得分:2)

我想说插入:O(n)删除:O(log n)。在一个集合中,不允许重复项目,并且应该忽略尝试插入重复项目,因为堆是完全填充的二叉树(底部除外),如果要插入到集合中,则搜索(项目)如果你发现它你什么都不做插入,所以插入可能需要O(n)进行查找和插入(你最多可以渗透n次)。 deleteMin具有o(log n)时间复杂度

答案 1 :(得分:2)

set semantics 引用的内容并不完全清楚,但作者可能意味着属性

A∪{x}∪{x} =A∪{x}

即。添加已在集合中的元素应该没有(可观察的)效果。

执行此操作的直接方法是在插入时检查重复项。但是,在普通的二进制堆中,删除任意元素需要O(n),这显然是相当慢的。

更聪明的想法可能是在删除最小元素时消除重复,重复删除直到我们看到新值。这需要O(k log n),其中k是检索节点的重复数。如果已知k是常数,则为O(log n)。然而,在最坏的情况下,k = n,使得最坏情况时间复杂度为O(n log n)。但是,如果我们测量的是分摊的时间复杂度,则该算法可以实现插入和移除的O(log n)。

通过使用平衡二叉搜索树而不是堆,可以实现插入和删除的最坏情况时间复杂度O(log n)。这是否符合" heap"目前尚不清楚。

总之,可能的答案是:

  • O(n),O(log n):有点天真的堆
  • O(log n),O(n log n):调整实际堆,最坏情况时间复杂度
  • O(log n),O(log n):调整实际堆,摊销时间复杂度
  • O(log n),O(log n):伪装成堆的平衡二进制搜索树

也就是说,根据我们解释问题的方式,不同的答案是正确的。