算法导论 — 6.1 堆

笔记

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

练习

6.1-1 在高度为hhh的堆中,元素个数最多和最少分别是多少?
  
  高度为hhh的堆一共有h+1h+1h+1层。第一层有111个元素,第二层有222个元素,第三层有444个元素,以此类推。除最后一层外,第iii层有2i−12^{i-1}2i1个元素。
  最后一层为第h+1h+1h+1层,最少有111个元素,最多有2h2^h2h个元素。因此,高度为hhh的堆中,最少元素个数为∑i=1h2i−1+1=2h\sum_{i=1}^h{2^{i-1}}+1 = 2^hi=1h2i1+1=2h;而最多元素个数为∑i=1h+12i−1=2h+1−1\sum_{i=1}^{h+1}2^{i-1} =2^{h+1}-1i=1h+12i1=2h+11
  
6.1-2 证明:含nnn个元素的堆的高度为⌊lgn⌋⌊{\rm lg}n⌋lgn
  
  利用练习6.1-1的结论,高度为hhh的堆中元素最少有2h2^h2h个,最多有2h+1−12^{h+1}-12h+11个,即2h≤n≤2h+1−12^h ≤ n ≤ 2^{h+1}-12hn2h+11。在nnn的这个取值范围内,必然有h=⌊lgn⌋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 证明:当用数组表示存储nnn个元素的堆时,叶结点下标分别为⌊n/2⌋+1,⌊n/2⌋+2,…,n⌊n/2⌋+1,⌊n/2⌋+2,…,nn/2+1n/2+2n
  
  考虑最后一个结点,其下标为nnn,它的父结点⌊n/2⌋⌊n/2⌋n/2必然是最后一个非叶结点,而之后的结点必然都为叶结点。所以叶结点下标为⌊n/2⌋+1,⌊n/2⌋+2,…,n⌊n/2⌋+1,⌊n/2⌋+2,…,nn/2+1n/2+2n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值