算法导论 — 6.1 堆

笔记

本节主要给出(二叉)堆的定义。堆是一种用数组保存的完全二叉树。完全二叉树的意思是,除了树的最底层,其他层都完全充满的。树中的元素按照从上到下、从左到右的顺序保存在数组中。下图给出了堆的一个例子,左图是完全二叉树的形式,右图是堆在数组中的表示。
  在这里插入图片描述
  如果用 A A A表示堆所在的数组,那么 A . l e n g t h A.length A.length表示数组的容量,即数组最多可容纳的元素的个数; A . h e a p _ s i z e A.heap\_size A.heap_size表示堆中的元素个数。显然有 A . h e a p _ s i z e ≤ A . l e n g t h A.heap\_size ≤ A.length A.heap_sizeA.length。树的根结点是元素 A [ 1 ] A[1] A[1]
  给定一个结点的下标 i i i,根据下式可以得到它的父结点、左孩子和右孩子的下标:
  在这里插入图片描述
  以上3个公式成立的前提是数组下标从1开始,这是《算法导论》这部书的约定。我们写C/C++代码时,数组下标是从0开始的。在这种情况下,上面3个公式应当变为
  在这里插入图片描述
  二叉堆分两种:最大堆最小堆。在最大堆中,除了根以外的所有结点 i i i都要满足以下性质。即对于任意一棵子树,子树的根结点一定是子树的最大元素。
  在这里插入图片描述
  相反地,在最小堆中,除了根以外的所有结点 i i i都要满足以下性质。即对于任意一棵子树,子树的根结点一定是子树的最小元素。
  在这里插入图片描述

练习

6.1-1 在高度为 h h h的堆中,元素个数最多和最少分别是多少?
  
  高度为 h h h的堆一共有 h + 1 h+1 h+1层。第一层有 1 1 1个元素,第二层有 2 2 2个元素,第三层有 4 4 4个元素,以此类推。除最后一层外,第 i i i层有 2 i − 1 2^{i-1} 2i1个元素。
  最后一层为第 h + 1 h+1 h+1层,最少有 1 1 1个元素,最多有 2 h 2^h 2h个元素。因此,高度为 h h h的堆中,最少元素个数为 ∑ i = 1 h 2 i − 1 + 1 = 2 h \sum_{i=1}^h{2^{i-1}}+1 = 2^h i=1h2i1+1=2h;而最多元素个数为 ∑ i = 1 h + 1 2 i − 1 = 2 h + 1 − 1 \sum_{i=1}^{h+1}2^{i-1} =2^{h+1}-1 i=1h+12i1=2h+11
  
6.1-2 证明:含 n n n个元素的堆的高度为 ⌊ l g n ⌋ ⌊{\rm lg}n⌋ lgn
  
  利用练习6.1-1的结论,高度为 h h h的堆中元素最少有 2 h 2^h 2h个,最多有 2 h + 1 − 1 2^{h+1}-1 2h+11个,即 2 h ≤ n ≤ 2 h + 1 − 1 2^h ≤ n ≤ 2^{h+1}-1 2hn2h+11。在 n n n的这个取值范围内,必然有 h = ⌊ l g n ⌋ h=⌊{\rm lg}n⌋ h=lgn
  
6.1-3 证明:在最大堆的任一子树中,该子树所包含的最大元素在该子树的根结点上。
  

6.1-4 假设一个最大堆的所有元素都不相同,那么该堆的最小元素应该位于哪里?
  
  最小元素可以位于任意一个叶子结点上。

6.1-5 一个已排好序的数组是一个最小堆吗?
  
  如果一个数组已按升序排好序,那么它就是一个最小堆。如果数组按降序排序,那么它是一个最大堆。

6.1-6 值为<23, 17, 14, 6, 13, 10, 1, 5, 7, 12>的数组是一个最大堆吗?
  
  如果画出二叉树,我们会发它并不是一个最大堆。
  在这里插入图片描述

6.1-7 证明:当用数组表示存储 n n n个元素的堆时,叶结点下标分别为 ⌊ n / 2 ⌋ + 1 , ⌊ n / 2 ⌋ + 2 , … , n ⌊n/2⌋+1,⌊n/2⌋+2,…,n n/2+1n/2+2n
  
  考虑最后一个结点,其下标为 n n n,它的父结点 ⌊ n / 2 ⌋ ⌊n/2⌋ n/2必然是最后一个非叶结点,而之后的结点必然都为叶结点。所以叶结点下标为 ⌊ n / 2 ⌋ + 1 , ⌊ n / 2 ⌋ + 2 , … , n ⌊n/2⌋+1,⌊n/2⌋+2,…,n n/2+1n/2+2n

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值