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

6.1-1算法


 

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

 

6.1-2spa


 

  這很好想,可是很差證實。code

  由已知高度爲 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⌋ 。blog

 

6.1-3排序


 

  最大堆的屬性告訴咱們除了根結點之外的全部結點都要知足 A[PARENT(I)] >= A[I] ,一棵樹是遞歸定義的,因此子樹的最大結點確定是其根結點。遞歸

 

6.1-4索引


 

  它必定是葉子結點,位於 ⌊lgn⌋ 或 ⌊lgn⌋ - 1 層class

 

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 開始(最大)堆化,而後是 三、二、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 的堆,其高度與最大結點數的關係仍是上式。

相關文章
相關標籤/搜索