在最大堆中查找第7大的元素?

3
我的朋友和我在这个问题上有不同的看法。问题是:在具有 n 个元素的最大堆中查找第 7 大的元素的时间复杂度是多少?
我认为它应该是 O(n),而她认为它应该是 O(1)。我的逻辑是,假设 n 是 7,那么第七个最大的元素将是堆中的最后一个元素,所以如果考虑最坏情况,时间复杂度应该是 O(n)。然而,她说既然它是最大堆,那么查找第七个最大的元素应该只需要常数时间。但按照她的逻辑,甚至第 50 个或第 100 个最大的元素也可以在 O(1) 的时间内找到。此外,在我们遇到这个问题的书中,答案是 O(logn)。
请问哪种解决方案是正确的?
3个回答

6

在最大堆中查找第七大元素的简单算法是:

repeat 6 times:
    del-max(heap)
return max(heap)

第一个循环执行恒定数量的del-max操作,每次操作需要O(lg n)的时间。 max操作需要常数时间。 执行del-max操作占主导地位,导致总复杂度为O(lg n)。 我并不是声称这是最优解。

2
我对堆不是很熟悉,但你指的是 最大值 而不是 最小值 吧?删除了最小的六个元素后,新的最小值却是原来第七个 最大的 元素,听起来不太合理。 - Silly Freak
2
实际上它是O(k log n),其中k是项目数量。不是O(log n)。 - Jim Mischel
@bigbong 这在任何一本好的算法教材和Wikipedia中都有介绍。除了 del-max,它还可以被称为 deleteextract-max 等等。 - Fred Foo
哦,是的...我没有将其与提取最大值相关联。明白了。非常感谢。 - bigbong
请注意,这样做会修改堆。因此,您并不是在堆中搜索第k个最大的元素。相反,您正在从堆中删除前k个元素。 - Jim Mischel
1
@bigbong 感谢您的接受,但实际上其他答案提供了更好的算法和更紧密的界限。您可能想要取消接受我的回答。 - Fred Foo

4
有一种O(1)的解决方案。假设堆被表示为一棵树,最大元素是根节点。那么第七大元素的节点与根节点之间的距离小于或等于6。与根节点距离<=6的节点数永远不会超过1 + 2 + 4 + 8 + 16 + 32 + 64 = 127个,这是一个常数。它们可以在常数时间内遍历到。

1
如果k是一个常数,那么2^k就是O(1)。 - kraskevich
确实,+1。只要 k 相对于 n 是固定的,这就是 O(1)。 - Fred Foo
所以,我想如果n为常数,插入排序n个元素需要恒定的时间。也就是说,我可以使用插入排序在常数时间内对100个元素的数组进行排序。毕竟,100是一个常数,所以100^2也是一个常数。虽然从技术上讲是正确的,但并不是特别有用的知识。 - Jim Mischel
2
是的,第99个是O(1),n-1不是。 - kraskevich
1
是的。在复杂度分析中,通常认为n是无限大的。 - kraskevich
显示剩余9条评论

3

对于一个大小为n的堆,其中n >> k,存在一种O(k)的算法来选择第k个元素。可以查看Greg Frederickson的An Optimal Algorithm for Selection in a Min-Heap获取PDF下载链接(位于左上角)。

因此,答案是你、你的朋友和正在阅读的书都错了。


但是由于这里k = 7,我们将具有O(7)的复杂度...那么这不会将问题降低到仅为O(1)吗? - bigbong
1
是的。如果您将 k 保持不变,则复杂度是恒定的。 - Jim Mischel
好的,明白了。谢谢。 - bigbong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接