1. 程式人生 > >《算法導論》第六章 練習題 Exercise

《算法導論》第六章 練習題 Exercise

chan idt 告訴 mage 最大 關鍵字 樹堆 return while

6.1-1


  在高度為 h 的堆中,元素最多有 2h+1 - 1 個,最少有 2h 個。註意算法導論裏的高度是指深度,從 0 開始而不是從 1 開始。

6.1-2


  這很好想,但是不好證明。

  由已知高度為 h 的堆,它的元素個數滿足 2h <= n <= 2h+1 - 1 ,解出 lg(n+1) - 1 <= h <= lgn ,但是它不夠“合理”,因為當 n = 2h+1-1 時,n 等於 2的冪 - 1,此時 lg(n+1) -1 = ?lgn? ,所以 ?lgn? <= h <= lgn 。而我們默認高度 h 是一個自然數,所以左右界一致,得出 h = ?lgn? 。

6.1-3


  最大堆的屬性告訴我們除了根結點以外的所有結點都要滿足 A[PARENT(I)] >= A[I] ,一棵樹是遞歸定義的,所以子樹的最大結點肯定是其根結點。

6.1-4


  它一定是葉子結點,位於 ?lgn? 或 ?lgn? - 1 層

6.1-5


  按遞增排序的話,是的

6.1-6


  不是,"PARENT" 6 < "CHILD" 7

6.1-7


  通過反證法比較好證明。

  假設 i ∈ { ?n/2?+1, ?n/2?+2, ... , n } ,那麽它的孩子的序號至少是 2·(?n/2?+1), 2·(?n/2?+2) ,顯然不在數組內。

  所以可以得到結論:堆中葉子結點數 = ?n+1?

6.2-1


   3 先與左右兒子比較,找到其中最大的關鍵字並記錄它的索引,讓它與 3 交換,遞歸調用實現 3 的子樹堆化。

6.2-2


  維護最小堆的算法如下:

#define LEFT(i) (2*i + 1)
#define RIGHT(i) (2*i + 2)

MIN-HEAPIFY (A, i)
    left = LEFT (i)
    right = RIGHT (i)
    if left <= A.HEAPSIZE && A[left] < A[i]
        min_index 
= left else min_index = i if right <= A.HEAPSIZE && A[right] < A[min_index] min_index = right if min_index != i exchange A[i] and A[min_index] MIN-HEAPIFY(A, min_index)

  時間一樣,都是 Θ(lgn)

6.2-3


  不會進行遞歸堆化。  

6.2-4


  其子結點的序號超出了堆的大小,程序將視為其子結點不存在,所以不會進行堆化操作。

6.2-5


  尾遞歸改循環控制結構如下:  

#define LEFT(i) (2*i + 1)
#define RIGHT(i) (2*i + 2)

MAX-HEAPIFY (A, i)
    while i < A.HEAPSIZE
        left = LEFT(i)
        right = RIGHT(i)

        if left < A.HEAPSIZE && A[left] > A[i]
            max_index = left
        else
            max_index = i

        if right < A.HEAPSIZE && A[right] > A[max_index]
            max_index = right

        if max_index != i 
            exchange A[max_index] and A[i]
        else
            return;

6.2-6


  ...

6.3-1


  從 ?A.length/2? 開始,即第一個非葉子結點 10 開始(最大)堆化,然後是 3、2、1 。過程很簡單,直接寫結果了,得到的數組是 {84, 22, 19, 10, 3, 17, 6, 5, 9}

6.3-2


  我們從 ?n/2? 開始的目的是要讓每次叠代前後 i 都是最大堆的根。如果從 1 開始,那麽將無法保持最大堆的特性(無法保證循環不變式)。

6.3-3

  這裏將利用到 6.1-7 的結論:堆中葉子結點數 = ?n/2?

  首先,當 h = 0 時(算法導論中高度深度都是從 0 開始),高度為零的堆就是葉子結點組成的堆,有 ?n/2? 個這樣的堆,結點數是 ?n/2?

  假設當 h = h-1 時,結論成立。

  有一顆高度為 h 的堆,如果把它的葉子結點都剪去後它將變成高度為 h - 1 、結點數為 n - ?n/2? = ?n/2? 的堆,代入 h = h-1 時的結論,有如下推導:

  技術分享圖片

  同理,我們可以用高度為 h+1 的堆剪去葉子結點得到高度為 h 的堆,其高度與最大結點數的關系還是上式。

  

      

《算法導論》第六章 練習題 Exercise