MAX_HEAPIFY 算法和最坏情况的递归关系

Posted

技术标签:

【中文标题】MAX_HEAPIFY 算法和最坏情况的递归关系【英文标题】:Recursive relation for the MAX_HEAPIFY algorithm and the worst case 【发布时间】:2021-08-11 09:44:07 【问题描述】:

通过CLRS 时,我发现了 max-heapify 算法的递归关系。事实上,我的老师已经证明了,max-heapify 过程的时间复杂度是 O(logn),因为最坏的情况是根必须“冒泡/向下浮动” ' 从顶部一直到最后一层。这意味着我们逐层移动,因此步数等于堆的层数/高度,正如我们所知,它以 logn 为界。很公平。

然而,通过递归关系以更严格的方式在 CLRS 中证明了这一点。据说最坏的情况发生在最后一层填满一半时,has already been explained here. 所以据我从那个答案中了解到,他们在数学上得出了这个结论:我们想要最大化左子树的大小 relative到堆大小n,即最大化L/n的值。为了实现这一点,我们必须将最后一层填充一半,以使 L(左子树)中的节点数最大化并且 L/n 最大化。

在最后一层添加更多的节点会增加节点的数量,但不会改变 L 的值。所以 L/n 会随着堆变得更加平衡而减少。只要是数学的,一切都很好。

现在这就是我卡住的地方:假设我在这个半满的关卡中再添加一个节点。实际上,我看不到这如何以某种方式减少发生的步骤/比较的数量,并且不再是最坏的情况。即使我又添加了一个节点,但所有的比较只发生在左子树中,与右子树无关。有人可以说服我/帮助我了解 L/n 必须在最坏的情况下最大化的原因和确切方式吗?我会很感激一个示例输入以及如何添加更多节点不再使其成为最坏的情况?

【问题讨论】:

【参考方案1】:

假设我在这个半满的关卡中再添加一个节点。实际上,我看不到这如何以某种方式减少发生的步骤/比较的数量并且不再是最坏的情况。即使我又添加了一个节点,但所有的比较只发生在左子树上,与右子树无关。

这并没有减少步数是正确的。然而,当我们谈到时间复杂度时,我们会寻找步数与 ? 之间的关系。如果只看步数,我们只会得出结论,最坏的情况发生在树无限大时。虽然这是一个非常糟糕的情况(最坏的情况),但这并不是本书所说的“最坏情况”的意思。我们感兴趣的不仅仅是步数,还有这个数字与?的关系。

我们可以在这里讨论术语,因为通常“最坏情况”不是关于依赖于?的东西,而是关于给定 ?可能存在的变体。例如,在讨论排序算法的最坏情况时,最坏和最好的情况取决于输入数据的组织方式(已经排序、反转等)。这里“最坏情况”用于树(底层)的形状,它直接由 ? 的值推断出来。一旦你有了?,那里就没有变化了。

然而,对于递归关系,我们必须找到公式——根据?——给出左子树中子树数量的上限,约束条件是:希望这个公式使用简单的算术(例如:没有地板)。

这是一个图表,其中蓝色条表示?的值,橙色条表示左子树中的节点数。

递归关系是基于两个子树的最大子树都是左子树的思想,所以它代表最坏的情况。该子树有许多节点,介于 (?-1)/2 和 2?/3 之间。左子树满时,左子树节点数与总节点数之比最大,右子树高度较小。

这是用比率表示的相同数据:

您可以看到这些最大值出现的位置:当 ? 为 2、5、11、23...时,左子树中的节点数与 ? 之间的比率接近 40%。这 40% 代表比率的上限,对于 ? 的所有值来说是一个安全的“包罗万象”。

我们在递归关系中需要这个比率:40% 可以改写:子树中的节点数的上限为 2?/3。所以递归关系是

            ?(?) = ?(2?/3) + O(1)

【讨论】:

以上是关于MAX_HEAPIFY 算法和最坏情况的递归关系的主要内容,如果未能解决你的问题,请参考以下文章

渐近时间复杂度与最佳、平均和最坏情况输入的组合

线性递归、二元递归与运行时的关系

【比较难写的算法】最坏情况线性时间的选择

排序算法

归并排序(递归非递归以及自然归并排序)算法总结

插入排序