《算法导论》第三版第6章 堆排序 练习思考题 个人答案
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<2h+12^h\leq n\leq 2^{h+1}-1<2^{h+1}2h≤n≤2h+1?1<2h+1
h≤lg?n<h+1h\leq\lg n<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 = largest6.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] = key6.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_ye.
解:
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.
思路:從矩陣的右上方(或左下方)開始比較,如果矩陣中的元素比較大,就繼續向左(向上)比較,反之則向下(向右)比較。
解:
總結
以上是生活随笔為你收集整理的《算法导论》第三版第6章 堆排序 练习思考题 个人答案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何快速将文本中的tab更换成逗号(图文
- 下一篇: RS232转PROFINET网关链接扫码