6.1 堆

6.1-1

解:2h+1−12^{h+1}-12h+1−1;2h+12^h+12h+1

6.1-2

证明:
2h≤n≤2h+1−1&lt;2h+12^h\leq n\leq 2^{h+1}-1&lt;2^{h+1}2h≤n≤2h+1−1<2h+1
h≤lg⁡n&lt;h+1h\leq\lg n&lt;h+1h≤lgn<h+1
h=⌊lg⁡n⌋h=\lfloor\lg n\rfloorh=⌊lgn⌋

6.1-3

由最大堆性质可知。

6.1-4

解:叶子结点。

6.1-5

解:升序的话,是。

6.1-6

解:不是。

6.1-7

解:n是最后一个元素→n的父结点是最后一个父结点且n的父结点为⌊n/2⌋\lfloor n/2\rfloor⌊n/2⌋→结论。

6.2 维护堆的性质

6.2-1

解:⟨27,17,3,16,13,10,1,5,7,12,4,8,9,0⟩⟨27,17,10,16,13,3,1,5,7,12,4,8,9,0⟩⟨27,17,10,16,13,9,1,5,7,12,4,8,3,0⟩\begin{aligned} \langle 27, 17, 3, 16, 13, 10,1, 5, 7, 12, 4, 8, 9, 0 \rangle \\ \langle 27, 17, 10, 16, 13, 3, 1, 5, 7, 12, 4, 8, 9, 0 \rangle \\ \langle 27, 17, 10, 16, 13, 9, 1, 5, 7, 12, 4, 8, 3, 0 \rangle \\ \end{aligned} ⟨27,17,3,16,13,10,1,5,7,12,4,8,9,0⟩⟨27,17,10,16,13,3,1,5,7,12,4,8,9,0⟩⟨27,17,10,16,13,9,1,5,7,12,4,8,3,0⟩​

6.2-2

MIN-HEAPIFY(A, i)
l = LEFT(i)
r = RIGHT(i)
if l <= A.heap-size and A[l] < A[i]smallest = l
else smallest = i
if r <= A.heap-size and A[r] < A[smallest]smallest = r
if smallest !=iexchange A[i] with A[smallest]MIN-HEAPIFY(A, smallest)

运行时间相等。

6.2-3

解:自动退出。

6.2-4

解:自动退出。

6.2-5

解:

MAX-HEAPIFY(A, i)
while i <= A.length / 2l = LEFT(i)r = RIGHT(i)if l <= A.heap-size and A[l] > A[i]largest = lelse largest = iif r <= A.heap-size and A[r] > A[largest]largest = rif largest != iexchange A[i] with A[largest]i = largest

6.2-6

证明(来自参考答案):
If you put a value at the root that is less than every value in the left and right subtrees, then MAX-HEAPIFY\text{MAX-HEAPIFY}MAX-HEAPIFY will be called recursively until a leaf is reached. To make the recursive calls traverse the longest path to a leaf, choose values that make MAX-HEAPIFY\text{MAX-HEAPIFY}MAX-HEAPIFY always recurse on the left child. It follows the left branch when the left child is greater than or equal to the right child, so putting 000 at the root and 111 at all the other nodes, for example, will accomplish that. With such values, MAX-HEAPIFY\text{MAX-HEAPIFY}MAX-HEAPIFY will be called hhh times (where hhh is the heap height, which is the number of edges in the longest path from the root to a leaf), so its running time will be Θ(h)\Theta(h)Θ(h) (since each call does Θ(1)\Theta(1)Θ(1) work), which is Θ(lg⁡n)\Theta(\lg n)Θ(lgn). Since we have a case in which MAX-HEAPIFY\text{MAX-HEAPIFY}MAX-HEAPIFY's running time is Θ(lg⁡n)\Theta(\lg n)Θ(lgn), its worst-case running time is Ω(lg⁡n)\Omega(\lg n)Ω(lgn).

6.3 建堆

6.3-1

略。。。

6.3-2

思路:因为MAX-HEAPIFY的前提是左右均为最大堆,如果递增岂不是一开始就是最大堆?

6.3-3

思路:可使用归纳法证明。

6.4 堆排序算法

6.4-1

6.4-2

证明:
初始化:子数组A[i+1…n]为空,因此不变式成立。
保持:A[1]是A[1…i]中的最大元素,它小于A[i+1…n]中的元素。当我们把它放在第i个位置时,A[i…n]包含最大的元素,且已排好序。减小堆大小并调用MAX-HEAPIFY将A[1…i-1]转换为最大堆。递减i为下一次迭代设置不变量。
终止:循环后i=1。这意味着A[2…n]被排序,A[1]是数组中的最小元素,这使得数组被排序。

6.4-3

解:Θ(nlg⁡n)\Theta(n\lg n)Θ(nlgn);Θ(nlg⁡n)\Theta(n\lg n)Θ(nlgn)

6.4-4

由6.4-3可得。

6.4-5

证明(来自参考答案):
This proved to be quite tricky. My initial solution was wrong. Also, heapsort appeared in 1964, but the lower bound was proved by Schaffer and Sedgewick in 1992. It’s evil to put this an exercise.
Let’s assume that the heap is a full binary tree with n=2k−1n = 2^k - 1n=2k−1. There are 2k−12^{k - 1}2k−1 leaves and 2k−1−12^{k - 1} - 12k−1−1 inner nodes.
Let’s look at sorting the first 2k−12^{k - 1}2k−1 elements of the heap. Let’s consider their arrangement in the heap and color the leaves to be red and the inner nodes to be blue. The colored nodes are a subtree of the heap (otherwise there would be a contradiction). Since there are 2k−12^{k - 1}2k−1 colored nodes, at most 2k−22^{k - 2}2k−2 are red, which means that at least 2k−2−12^{k - 2} - 12k−2−1 are blue.
While the red nodes can jump directly to the root, the blue nodes need to travel up before they get removed. Let’s count the number of swaps to move the blue nodes to the root. The minimal case of swaps is when (1) there are 2k−2−12^{k - 2} - 12k−2−1 blue nodes and (2) they are arranged in a binary tree. If there are ddd such blue nodes, then there would be i=lg⁡di = \lg di=lgd levels, each containing 2i2^i2i nodes with length iii. Thus the number of swaps is,
∑i=0lg⁡di2i=2+(lg⁡d−2)2lg⁡d=Ω(dlg⁡d).\sum_{i = 0}^{\lg d}i2^i = 2 + (\lg d - 2)2^{\lg d} = \Omega(d\lg d).i=0∑lgd​i2i=2+(lgd−2)2lgd=Ω(dlgd).
And now for a lazy (but cute) trick. We’ve figured out a tight bound on sorting half of the heap. We have the following recurrence:
T(n)=T(n/2)+Ω(nlg⁡n).T(n) = T(n / 2) + \Omega(n\lg n).T(n)=T(n/2)+Ω(nlgn).
Applying the master method, we get that T(n)=Ω(nlg⁡n)T(n) = \Omega(n\lg n)T(n)=Ω(nlgn).

6.5 优先队列

6.5-1

略。。。

6.5-2

6.5-3

解:

HEAP-MINIMUM(A)
return A[1]
HEAP-EXTRACT-MIN(A)
if A.heap-size < 1error "heap underflow"
min = A[1]
A[1] = A[A.heap-size]
A.heap-size = A.heap-size - 1
MIN-HEAPIFY(A, 1)
return min
HEAP-DECREASE-KEY(A, i, key)
if key > A[i]error "new key is larger than current key"
A[i] = key
while i > 1 and A[PARENT(i)] > A[i]exchange A[i] with A[PARENT(i)]i = PARENT(i)
MIN-HEAP-INSERT(A, key)
A.heap-size = A.heap-size + 1
A[heap-size] = ∞
HEAP-DECREASE-KEY(A, A.heap-size, key)

6.5-4

解:保证key>A[A.heap-size]

6.5-5

证明:
初始化:A是一个堆,除了A[i]可能比它的父结点更大,因为它已被修改。A[i]比其子节点大,因为否则警戒将失败并且不会输入循环(新值大于旧值并且旧值大于子节点)。
保持:当我们用父结点交换A[i]时,除了A[PARENT(i)]可能比它的父结点更大之外,满足最大堆属性。 将i更改为其父结点会保持不变量。
终止:每当堆耗尽或A[i]及其父结点的最大堆属性被保留时,循环就会终止。在循环终止时,A是最大堆。

6.5-6

解:

HEAP-INCREASE-KEY(A, i, key)
if key < A[i]error "new key is small than current key"
A[i] = key
while i > 1 and A[PARENT(i)] < keyA[i] = A[PARENT(i)]i = PARENT(i)
A[i] = key

6.5-7

解:
队列:将HEAP-EXTRACT-MAX改为HEAP-EXTRACT-MIN。
栈:INSERT时保证值最大。

6.5-8

解:

HEAP-DELETE(A, i):A[i] = A[A.heap-size]A.heap-size = A.heap-size - 1MAX-HEAPIFY(A, i)

6.5-9

思路:取各链表第一个元素建最小堆。

思考题

6-1 (用插入的方法建堆)

a.

解:否;假设输入数据为1,2,3……

b.

证明思路:MAX_HEAP_INSERT是一个Θ(lgn)的操作,并需要调用Θ(n)次。

6-2 (对d叉堆的分析)

a.

解:
PARENT(i) = ⌊i/d⌋,当i mod d = 0, 1
PARENT(i) = ⌈i/d⌉,当i mod d = 2, … , d-1
CHILD(i) = di-d+2, … , di+1

b.

解:⌈logd[n(d-1)+1]⌉

c.

解:

EXTRACT-MAX(A)
if A.heap-size < 1error "heap underflow"
max = A[1]
A[1] = A[A.heap-size]
A.heap-size = A.heap-size - 1
MAX-HEAPIFY(A, 1, d) // 此处d为叉数
return max
MAX-HEAPIFY(A, i, d)
largest = i
for k = di-d+2 to di+1if k <= A.heap-size and A[k] > A[largest]largest = k
if larget != iexchange A[i] with A[largest]MAX-HEAPIFY(A, largest, d)

O(dlogdn)

d.

解:

INSERT(A, key)
A.heap-size = A.heap-size + 1
A[A.heap-size] = -∞
INCREASE-KEY(A, A.heap-size, key)

O(logdn)

e.

解:

INCREASE-KEY(A, i, key)
if key < A[i]error "new key is smaller than current key"
A[i] = key
while i > 1 and A[PARENT(i)] < A[i]exchange A[i] with A[PARENT(i)]i = PARENT(i)

O(logdn)

6-3 (Young氏矩阵)

a.

解:
2 3 4 5
8 9 12 14
16 ∞ ∞ ∞
∞ ∞ ∞ ∞

b.

证明思路:可以先对行(或列)使用归纳法进行证明,再扩展至另一维度。

c.

解:

EXTRACT-MIN(A, m, n)
if m < 1 or n < 1error "matrix underflow"
min = A[1, 1]
A[1, 1] = A[m, n]
A[m, n] = ∞
MIN-MATRIX(A, m-1, n) // or (A, m, n-1)
MIN-MATRIX(A, m, n, x, y)
smallest = A[x, y]
smallest_x = x
smallest_y = y
if x + 1 <=m and A[x+1, y] < smallestsmallest = A[x+1, y]smallest_x = x + 1
if y + 1 <= n and A[x, y+1] < smallestsmallest = A[x, y+1]smallest_x = xsmallest_y = y + 1
if smallest != A[x, y]exchange A[x, y] with A[smallest_x, smallest_y]MIN_MATRIX(A, m, n, smallest_x, smallest_y)

d.

解:

MATRIX-INSERT(A, m, n, key)
A[m, n] = key
x = m
y = n
while (x > 1 or y > 1) and flag == 0flag = 1if x >= 2 and A[x-1, y] > A[x, y]larger_x = x - 1larger_y = yflag = 0if n >= 2 and A[x, y-1] > A[larger_x, larger_y]larger_x = xlarger_y = y - 1flag = 0if flag == 0exchange A[x, y] with A[larger_x, larger_y]x = larger_xy = larger_y

e.

解:

YOUNG-MATRIX-SORT(A, m, n)
let B be a new array
for i = 1 to n^2B[i] = EXTRACT-MIN(A)

n2·O(m+n) = n2·O(2n) = O(n3)

f.

思路:从矩阵的右上方(或左下方)开始比较,如果矩阵中的元素比较大,就继续向左(向上)比较,反之则向下(向右)比较。
解:

YOUNG-MATRIX-SEARCH(A, m, n, key)
x = m
y = 1
while x >1 and y < nif A[x, y] == keyreturn x, yelse if A[x, y] < keyy = y + 1else x = x - 1
return NIL

《算法导论》第三版第6章 堆排序 练习思考题 个人答案相关推荐

  1. 算法导论第三版第十一章11.1-4

    算法导论第三版第十一章11.1-4 我们希望在一个非常大的数组上,通过利用直接寻址的方式来实现一个字典.开始时,该数组中可能包含一些无用信息,但要堆整个数组进行初始化时不太实际的,因为该数组的规模太大 ...

  2. 算法导论第三版第8章思考题

    8-1 a. 因为对于每一种输入,不可能能够到达同一片叶子,所以一共有 n! n!片子是可以到达的.其次因为输入完全随机,每种输入概率相等且到叶子结点的路径是固定的,这 n! n!个叶子结点的概率也是 ...

  3. 算法导论第三版 第15章习题答案

    2020/11/18:初稿,增加Python代码实现,修订参考文献部分错误(如15.1的第4题) 参考文献: https://walkccc.github.io/CLRS/Chap15/ https: ...

  4. 算法导论第三版 第2章习题答案

    2020/10/27: 增加伪代码相应的Python实现代码. 2020/11/13:修订第2节第3题的bug. 参考文献:https://ita.skanev.com/ 2 Getting Star ...

  5. 算法导论第三版(参照自己理解和网上的答案,仅供自己学习)

    第一章 1.1-1 给出现实生活中需要排序的一个例子或者现实生活中需要计算凸壳的一个例子 答:(1)排序:在网上购物挑选物品过程中需要按照某种规则筛选(如按照价格由低到高),这种我自己认为是当前最简单 ...

  6. 带权中位数-算法导论第三版第九章思考题9-2

    带权中位数-算法导论第三版第九章思考题9-2 b 时间复杂度O(nlgn) float find_median_with_weights_b(float *array,int length) {qui ...

  7. 算法导论第三版第二章思考题答案

    算法导论第三版第二章思考题答案 第二章思考题 算法导论第三版第二章思考题答案 2.1 2.2 2.3 2.4 汇总传送门 2.1 #include<iostream> using name ...

  8. 算法导论第三版3.1答案

    算法导论第三版3.1答案 这一章数学公式实在太多了..打不过来,为了节约时间就用纸笔写了. 2.2 算法导论第三版3.1答案 汇总传送门 汇总传送门 链接: [算法导论习题答案汇总]

  9. 给出TREE_INSERT过程的非递归版本(算法导论第三版12.3-1)

    给出TREE_INSERT过程的非递归版本(算法导论第三版12.3-1) template<typename T> void insert_recursive(BinaryTree< ...

  10. 写出TREE-PREDECESSOR的伪代码(算法导论第三版12.2-3)

    写出TREE-PREDECESSOR的伪代码(算法导论第三版12.2-3) TREE-PREDECESSOR(x)if x.left != NILreturn TREE-MAXIMUM(x.left) ...

最新文章

  1. WebService的两种用户验证方式
  2. android modem开发(16)---MTK语音测试
  3. viewpager初始化fragment没有绘制_NDK OpenGL ES渲染系列 之 绘制三角形
  4. 二分图带权最大匹配费用流_简单理解二分图与匈牙利算法
  5. linux和python那个好学_Python和C#哪个好学?老男孩python
  6. 目标检测(八)--Faster R-CNN
  7. GetSystemInfo
  8. 20. 为包含指针的关联容器指定比较类型
  9. 关于TIME_WAIT重用与RFC1337
  10. 某中学校校园网络方案设计(课程设计)
  11. Nginx工作原理及基本使用
  12. 用国产编程语言CBrother做微信公众号后台开发太简单
  13. 跨网段和同网段的通信
  14. 插件制作教程 php,HYBBS插件开发教程 (简单插件) 初识篇
  15. 【Web技术】1477- Tauri:下一代桌面应用开发框架?
  16. UNITY 2015 大会 观展记录
  17. 【Python量化】风险平价策略
  18. H5直播答题并不难,看完这篇你也会
  19. spring2.5.6升级到4.3.7常见问题
  20. 根据RGB​值判断颜色是否深浅色(附深浅色颜色集合)

热门文章

  1. 基于TI8168平台的16路D1分辨率的DVR方案
  2. u-blox gps 串口驱动安装恢复解决方案
  3. 深入浅出MFC第二章笔记
  4. CMOS模拟集成电路版图设计课程
  5. backtrack5 oracle,BackTrack5(BT5)硬盘安装
  6. 计算机三级数据库技术 知识点
  7. 2022计算机三级数据库总结和经验(有免费题库)
  8. 计算机组成原理知识体系
  9. 泛微oa服务器文件,泛微OA根据文档的docid查询文档附件存放的路径
  10. 使用foobar2000批量修改视频封面,批量修改artist/album