在heapsort下限?

时间:2011-01-04 01:42:07

标签: algorithm complexity-theory big-o heapsort lower-bound

众所周知,heapsort的最坏情况运行时是Ω(n lg n),但我很难理解为什么会这样。特别是,heapsort的第一步(制作最大堆)需要时间Θ(n)。然后是n次删除。我理解为什么每个堆删除需要时间O(lg n);重新平衡堆涉及一个向下泡沫的操作,它在堆的高度花费时间O(h),并且h = O(lg n)。但是,我没有看到为什么第二步应该采用Ω(n lg n)。似乎任何单个堆出列都不一定会导致节点移动到顶部,从而一直向下冒泡。

我的问题是 - 有没有人知道有关heapsort最佳案例行为的良好下限证明?

3 个答案:

答案 0 :(得分:17)

所以我做了一些挖掘自己,看起来这个结果实际上是最近的!我能找到的第一个下限证据来自1992年,虽然heapsort本身是在1964年发明的。

正式的下限证据是由Schaffer和Sedgewick的“The Heaport分析”论文引起的。这是一个略微复述的证明版本,省略了一些技术细节。

首先,让我们假设n = 2 k - 1对于某些k,这可以保证我们有一个完整的二进制堆。我稍后将展示如何单独处理此案例。因为我们有2个 k - 1个元素,所以heapsort的第一遍将在Θ(n)中构建一个高度为k的堆。现在,考虑从这个堆中出列的前半部分,从堆中删除2个 k-1 节点。第一个关键观察是,如果您获取起始堆然后标记实际上最终出列的所有节点,它们将形成堆的子树(即,每个出列的节点都有一个也会出列的父节点)。您可以看到这一点,因为如果不是这种情况,那么会有一些节点(较大的)父节点虽然节点本身已经出列但没有出列,但这意味着这些值无序。

现在,考虑一下这个树的节点是如何在堆中分布的。如果你标记堆0,1,2,...,k - 1的级别,那么在级别0,1,2,...,k - 2中将会有一些这样的节点(也就是说,除了树的底层之外的所有东西)。为了使这些节点从堆中出列,它们必须交换到根,并且它们一次只能交换一个级别。这意味着降低heapsort运行时的一种方法是计算将所有这些值提升到根所需的交换次数。事实上,这正是我们要做的。

我们需要回答的第一个问题是 - 最大的2个 k-1 节点中有多少不在堆的底层?我们可以通过矛盾表明这不超过2 k-2 。假设堆底层中至少有2个 k-2 + 1个最大节点。那么这些节点的每个父节点也必须是k-2级的大节点。即使在最好的情况下,这意味着级别中必须至少有2个 k-3 + 1个大节点k - 2,这意味着在k - 3等级中至少有2个 k-4 + 1个大节点。总结所有这些节点,我们得到有2个 k-2 + 2 k-3 + 2 k-4 + ... + 2 0 + k大节点。但是这个值严格大于2 k-1 ,这与我们在这里仅使用2个 k-1 节点的事实相矛盾。

好的......我们现在知道底层最多有2个 k-2 大节点。这意味着在第一个k-2层中必须至少有2个 k-2 的大节点。我们现在问 - 在所有这些节点上,从该节点到根节点的距离是多少?好吧,如果我们有2个 k-2 节点位于完整堆中的某个位置,那么它们中最多2个 k-3 可以处于前k-3级,因此在k-2级中至少有2个 k-2 - 2 k-3 = 2 k-3 重节点。 ,需要进行的掉期总数至少为(k-2)2 k-3 。由于n = 2 k -1,k =Θ(lg n),因此该值为Θ(n lg n)。

答案 1 :(得分:3)

简单的观察答案是这样的: 堆中的项目是:

1
2
4
8
...
2^[log(n/4)]
and last level has between (1..2^[log(n/2)]) ==> (1,[n/2]) item, (by [] I mean Ceiling not roof)

例如,如果您有7个项目:

1
2
4

如果你有8项:

1
2
4
1

有两个不同的堆树,首先至少有n / 4 - 1个堆的项目在最后一级,或者没有,所以在最后一个之前至少有n/4 - 1个项目,在第一个如果需要O((n/4 - 1) * log(n/2))从堆中删除最后一个级别的项目,在第二种情况下需要O((n/4 - 1) * log(n/4))从前一级别删除项目。所以在这两种情况下,它只需要n(4 log(n))n / 4 - 1项,所以它是一个下限(很容易说它是紧的下限)。

答案 2 :(得分:1)

以下是使用CLRS术语的解决方案:
我们从最大堆开始,这是一个带有n元素的完整二叉树 我们可以说在完整的二进制文件中有n/2个叶子和n/2个内部节点 n/2HEAP-SORT次迭代从堆中删除最大的n/2元素 让S成为最大n/2元素的集合 叶子中n/4个元素最多只有S元素,因为内部节点中必须有n/4个元素。
Ln/4中来自S的最大元素 因此,如果来自n/4的{​​{1}}元素位于0级(叶级) 那么在1级必须至少有S个 让n/8为来自P的{​​{1}}个{1}}元素 HEAP-SORT的n/8次迭代可以将S的元素作为根的捷径 然后离开堆,但n/2中的元素必须一直到根,然后才能从堆中删除。
所以至少有L个操作, 这给我们一个Ω(nlgn)的运行时间 现在针对max-heap的情况,它的所有叶子都没有在0级。
P为0级叶子的数量。
在HEAP-SORT的(n/8)(lgn-1)次迭代之后,我们留下了最大堆 一个高度为k的完整二叉树 我们可以用同样的方式继续我们的证据 现在适用于k小于lgn-1个叶子的情况 设n/4为{0}中叶子中S的元素数 如果k,那么{1}}级别必须至少有S个元素 这是因为在级别1之上总共可以有k <= n/8个元素 我们以同样的方式继续证明 如果n/8,那么S中必须至少有n/4个元素位于第1级。
我们以同样的方式继续证明 我们得出结论,HEAP-SORT的运行时间是Ω(nlgn)。

相关问题