6.3-2 在BUILD-MAX-HEAP的第2行代码中,为什么希望循环下标i从向下取整leghth[A]/2降到1,而
不是从1升到向下取整leghth[A]/2?
因为如果用递增循环从下标i=1开始,那么i的两个左右子树对于任意排序的数组来说就可能出现
左右子树不是最大堆的情况(使用MAX-HEAPIFY(A,i)函数必须满足左右子树是最大堆)。
如果用递减循环从下标i=leghth[A]/2开始,那么根据6.1-7知i=leghth[A]/2的结点是刚开始
含有子结点的情况,这时,子结点所组成的树只含有1个结点,那么肯定满足最大堆的情况。
6.3-3 证明:在任一含n个元素的堆中,至多有向下取整n/2^(h+1)个高度为h的结点。
n个元素的堆中,总高度为H,则2^0+2^1+...+2^H=n =>2^(H+1)-1=n
利用数学归纳法:
当h=0(最底层的结点相对于叶子结点的高度为0,注意不是深度哦!)时,那么有n/2^(0+1)=
(2^(H+1)-1)/2=2^H-1/2=向下取整(2^H-1/2)=2^H 这个正好是完全二叉树最底层的结点数。当然
在堆中最底层可能结点数不满,那么就要小于这个值,所以当h=0时,至多有向下取整n/2^(h+1)个
高度为h的结点。得证!
假设h=k时,至多有向下取整n/2^(k+1)个高度为h的结点成立。
那么h=k(除了k=0层结点可能不满,其余k>0层都是满的。这是堆的定义)时,就有
(2^(H+1)-1)/2^(k+1)个结点。
那么h=k+1时,也就是比高度为k的高一层(根据高度定义和完全二叉树性质还有k>0的条件),那么
h=k+1结点数正好是h=k的一半,所以就应该有(1/2)(2^(H+1)-1)/2^(k+1)个结点,那么这个式子
可以转换为(2^(H+1)-1)/2^((k+1)+1)=n/2^(h+1),所以h=k+1时,符合题意。问题得
不是从1升到向下取整leghth[A]/2?
因为如果用递增循环从下标i=1开始,那么i的两个左右子树对于任意排序的数组来说就可能出现
左右子树不是最大堆的情况(使用MAX-HEAPIFY(A,i)函数必须满足左右子树是最大堆)。
如果用递减循环从下标i=leghth[A]/2开始,那么根据6.1-7知i=leghth[A]/2的结点是刚开始
含有子结点的情况,这时,子结点所组成的树只含有1个结点,那么肯定满足最大堆的情况。
6.3-3 证明:在任一含n个元素的堆中,至多有向下取整n/2^(h+1)个高度为h的结点。
n个元素的堆中,总高度为H,则2^0+2^1+...+2^H=n =>2^(H+1)-1=n
利用数学归纳法:
当h=0(最底层的结点相对于叶子结点的高度为0,注意不是深度哦!)时,那么有n/2^(0+1)=
(2^(H+1)-1)/2=2^H-1/2=向下取整(2^H-1/2)=2^H 这个正好是完全二叉树最底层的结点数。当然
在堆中最底层可能结点数不满,那么就要小于这个值,所以当h=0时,至多有向下取整n/2^(h+1)个
高度为h的结点。得证!
假设h=k时,至多有向下取整n/2^(k+1)个高度为h的结点成立。
那么h=k(除了k=0层结点可能不满,其余k>0层都是满的。这是堆的定义)时,就有
(2^(H+1)-1)/2^(k+1)个结点。
那么h=k+1时,也就是比高度为k的高一层(根据高度定义和完全二叉树性质还有k>0的条件),那么
h=k+1结点数正好是h=k的一半,所以就应该有(1/2)(2^(H+1)-1)/2^(k+1)个结点,那么这个式子
可以转换为(2^(H+1)-1)/2^((k+1)+1)=n/2^(h+1),所以h=k+1时,符合题意。问题得