算法导论 — 6.3 建堆

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yangtzhou/article/details/84781025

笔记

建堆的过程实际上是自底向上地对所有非叶结点调用MAX-HEAPIFY的过程。由于叶结点没有孩子,所以每一个叶结点都可以看是只包含一个元素的最大堆。而自底向上地调用MAX-HEAPIFY,是要保证在处理任意一个结点的时候,它的子树已经满足了最大堆性质,这是调用MAX-HEAPIFY的必要条件。
  在这里插入图片描述
  BUILD-MAX-HEAP的运行时间为O(n)O(n)。这一结果的推导过程可以参考书本上的描述,这里不做说明。
  下图给出了一个构建最大堆的例子。
  在这里插入图片描述

练习

6.3-1 参照图6-3的方法,说明BUILD-MAX-HEAP在数组A = <5, 3, 17, 10, 84, 19, 6, 22, 9>上的操作过程。
  
  在这里插入图片描述

6.3-2 对于BUILD-MAX-HEAP中第2行的循环控制变量ii来说,为什么我们要求它是从A.length/2⌊A.length/2⌋到1递减,而不是从1到A.length/2⌊A.length/2⌋递增呢?
  
  因为调用MAX_HEAPIFY(A, i)的先决条件是,结点ii的子树必须都已经满足最大堆条件。而节点ii的子树中的结点的下标都比ii要大,因此BUILD-MAX-HEAP中的循环控制变量ii必须是递减的。

6.3-3 证明:对于任一包含nn个元素的堆中,至多有n/2h+1⌈n/2^{h+1}⌉个高度为h的结点?
  
  首先考虑叶结点,它们的高度h=0h = 0,根据练习6.1-7的结论,含有nn个元素的堆的叶子结点的个数为nn/2=n/2=n/20+1n-⌊n/2⌋=⌈n/2⌉=⌈n/2^{0+1}⌉。因此命题对h=0h = 0是成立的。
  下面把原始堆H0H_0中的叶结点去掉,剩下的元素仍然构成一个堆H1H_1,并且H1H_1中的叶结点就是H0H_0中高度为11的结点。堆H1H_1的大小为n/2⌊n/2⌋,故H1H_1中的叶结点个数为n/2/2n/22⌈⌊n/2⌋/2⌉≤⌈n/2^2 ⌉。即原始堆H0H_0中高度为11的结点至多有n/22=n/21+1⌈n/2^2 ⌉=⌈n/2^{1+1}⌉个。因此,命题对h=1h = 1也是成立的。
  下面把堆H1H_1中的叶结点去掉,剩下的元素也构成一个堆H2H_2,并且H2H_2中的叶结点就是H0H_0中高度为22的结点。堆H2H_2的大小为n/2/2⌊⌊n/2⌋/2⌋(因为堆H1H_1的大小为n/2⌊n/2⌋,根据练习6.1-7的结论,堆H1H_1中的非叶结点个数为n/2/2⌊⌊n/2⌋/2⌋)。堆H2H_2中的叶子结点个数为n/2/2/2n/23⌈⌊⌊n/2⌋/2⌋/2⌉≤⌈n/2^3⌉。即原始堆H0H_0中高度为22的结点至多有n/23=n/22+1⌈n/2^3 ⌉=⌈n/2^{2+1}⌉个。因此,命题对h=2h = 2也是成立的。
  … …
  以此类推,在一个大小为nn的堆中,高度为hh的结点至多有n/2h+1⌈n/2^{h+1}⌉个。

展开阅读全文

没有更多推荐了,返回首页