Max-Heapify 中最坏的情况——你如何得到 2n/3?
Posted
技术标签:
【中文标题】Max-Heapify 中最坏的情况——你如何得到 2n/3?【英文标题】:Worst case in Max-Heapify - How do you get 2n/3? 【发布时间】:2012-02-24 07:51:09 【问题描述】:在 CLRS,第三版,第 155 页,给出了在 MAX-HEAPIFY 中,
每个孩子的子树的大小最多为 2n/3——最坏的情况 当树的底层恰好是半满时发生。
我明白为什么当树的底层正好是半满时最糟糕。而且这个问题也有回答worst case in MAX-HEAPIFY: "the worst case occurs when the bottom level of the tree is exactly half full"
我的问题是如何获得 2n/3?
为什么如果底层是半满的,那么子树的大小最多是2n/3?
如何计算?
谢谢
【问题讨论】:
这个博客提供了一个简单的计算:bit.ly/138f43F。 【参考方案1】:在每个节点恰好有 0 个或 2 个子节点的树中,具有 0 个子节点的节点数比具有 2 个子节点的节点数多 1。说明:高度 h 的节点数为 2^h,由几何级数的求和公式等于(从高度0到h-1的节点之和)+ 1;并且从高度 0 到 h-1 的所有节点都是恰好有 2 个孩子的节点
ROOT
L R
/ \ / \
/ \ / \
----- -----
*****
设k为R中的节点数。L中的节点数为k + (k + 1) = 2k + 1。总节点数为n = 1 + (2k + 1) + k = 3k + 2(根加 L 加 R)。该比率为 (2k + 1)/(3k + 2),以 2/3 为界。没有小于 2/3 的常数起作用,因为 k 趋于无穷时的极限是 2/3。
【讨论】:
是的,我明白了,你的意思是 L / n = 2/3 哇。那很深。你自己是怎么想出来的?【参考方案2】:Understand the maximum number of elements in a subtree happens for the left subtree of a tree that has the last level half full.Draw this on a piece of paper to realize this.
一旦清楚了,2N/3的界限就很容易得到了。
让我们假设树中的节点总数为 N。
树中的节点数 = 1 +(左子树中的节点数)+(右子树中的节点数)
对于树的最后一层半满的情况,如果我们假设右子树的高度为 h,那么左子树的高度为 (h+1):
左子树的节点数=1+2+4+8....2^(h+1)=2^(h+2)-1 .....(i)
右子树的节点数 =1+2+4+8....2^(h) =2^(h+1)-1 .....(ii)
因此,插入:
树中的节点数 = 1 +(左子树中的节点数)+(右子树中的节点数)
=> N = 1 + (2^(h+2)-1) + (2^(h+1)-1)
=> N = 1 + 3*(2^(h+1)) - 2
=> N = 3*(2^(h+1)) -1
=> 2^(h+1) = (N + 1)/3
将这个值代入方程 (i),我们得到:
Number of nodes in Left Subtree = 2^(h+2)-1 = 2*(N+1)/3 -1 =(2N-1)/3 < (2N/3)
因此,对于具有 N 个节点的树,子树中最大节点数的上限为 2N/3。
【讨论】:
我还是不明白。是不是就算满了也不会发生,为什么一定要半满。有人解释一下 - 我很困惑。 @SundarRajan check math.stackexchange.com/questions/181022/… 特别是This is the most the heap can get imbalanced; adding another node will either begin to rebalance the heap (by filling out the other, right, half of the last level) or break the heap's shape property of being a complete binary tree
部分
很好的解释。【参考方案3】:
对于高度为h
的完全二叉树,节点数为f(h) = 2^h - 1
。在上述情况下,我们有几乎完整的二叉树,下半部分已满。我们可以将其可视化为root + left complete tree + right complete tree
的集合。如果原始树的高度是h
,那么左边的高度是h - 1
,右边的高度是h - 2
。所以方程变成了
n = 1 + f(h-1) + f(h-2)
(1)
我们想解决上面的f(h-1)
表示为n
f(h-2) = 2^(h-2) - 1 = (2^(h-1)-1+1)/2 - 1 = (f(h-1) - 1)/2
(2)
使用上面的(1)我们有
n = 1 + f(h-1) + (f(h-1) - 1)/2 = 1/2 + 3*f(h-1)/2
=> f(h-1) = 2*(n-1/2)/3
因此 O(2n/3)
【讨论】:
不是f(h) = 2^(h+1) - 1吗? 优秀的答案。请更正@afnrf 提到的 f(h)【参考方案4】:添加到 swen 的答案。当 k 趋于无穷时,(2k + 1) / (3k + 2) 如何趋于 2 / 3,
Lim_(k -> inf) (2k + 1) / (3k + 2) = Lim_(k -> inf) k(2 + 1 / k) / k(3 + 2 / k) = Lim_(k -> inf) (2 + 1 / k) / (3 + 2 / k)
应用限制,你得到 2/3
【讨论】:
【参考方案5】:节点数 -
0 级,即根为 2^0 1 级为 2^1 2 级为 2^2 ... 第n级为2^n从0级到n级所有节点的总和,
S = 2^0 + 2^1 + 2^2 + ... + 2^n从几何级数求和规则我们知道
x^0 + x^1 + x^2 + ... + x^(n) = (x^(n+1) - 1)/(x-1)代入x = 2,我们得到
S = 2^(n+1) - 1。即 2^(n+1) = S + 1由于 2^(n+1) 是第 n+1 层的节点总数,因此我们可以说具有 0 个子节点的节点数比具有 2 个子节点的节点数多 1。
现在让我们计算左子树、右树和总节点的数量..
假设根的左子树中的非叶节点数 = k。由上述推理,左子树的叶子节点数或 根 = k + 1。 root = k 的右子树中的非叶节点数,因为该树被称为恰好是半满的。
根的左子树的节点总数 = k + k + 1 = 2k +
树中的节点总数,n = (2k + 1) + k + 1 = 3k + 2。 左子树中的节点与总节点的比率 = (2k + 1) / (3k + 2) 以 2/3 为界。这就是说每个孩子的子树的大小最多为 2n/3 的原因。
【讨论】:
以上是关于Max-Heapify 中最坏的情况——你如何得到 2n/3?的主要内容,如果未能解决你的问题,请参考以下文章