1 堆排序演算法分析
MAX-HEAPIFY(A, i)
1 l ← LEFT(i)
2 r ← RIGHT(i)
3 if l ≤ heap-size[A] and A[l] > A[i]
4 then largest ← l
5 else largest ← i
6 if r ≤ heap-size[A] and A[r] > A[largest]
7 then largest ← r
8 if largest ≠ i
9 then exchange A[i] A[largest]
10 MAX-HEAPIFY(A, largest)
BUILD-MAX-HEAP(A)
1 heap-size[A] ← length[A]
2 for i ← ⌊length[A]/2⌋ downto 1
3 do MAX-HEAPIFY(A, i)
HEAPSORT(A)
1 BUILD-MAX-HEAP(A)
2 for i ← length[A] downto 2
3 do exchange A[1] A[i]
4 heap-size[A] ← heap-size[A] - 1
5 MAX-HEAPIFY(A, 1)
1.1 使用迴圈不變式證明演算法的正確性
初始化:首先,對於第一輪迭代開始之前,最大堆已經建好,A[1]數組儲存最大值。
保持:接下來,我們來考慮第二個性質:證明每一輪迴圈都能使迴圈不變式保持成立。在for迴圈2~5行的迭代開始時,子數組A[1..i]是一個包含了一個A[1..n]中的i個最小元素的最大堆;而子數組A[i+1..n]包含了已經排序的n-i個最大元素。
當i=k時,這時對應A[1]是剩餘數組的最大值,先交換A[1]和A[k]中的值,那麼交換後,A[1]很有可能不是剩餘數組A[1..k-1]中的最大值,這時調用MAX-HEAPIFY(A, 1),因為在調用前,除了根節點外,都是符合最大堆的要求,調用MAX-HEAPIFY(A, 1)子過程可以保證在這種情況下把這個放於根節點的小元素調整到合適位置,而保持A[1..k-1]仍然是最大堆。(調整的部分符合最大堆規則,沒有調整的部分也符合最大堆規則,因此可以保證)另外,A[1..k-1]是數組中最小的k-1個元素。而子數組A[k…n]包含了已排序的n-k+1個元素。這樣就證明了每一輪迴圈都能使迴圈不變式保持成立。
終止:最後,分析一下迴圈結束時的情況。對於堆排序,當i等於1時,迴圈結束。在迴圈不變式中,那麼意味著A[2..n]子數組包含了原來數組的最大的n-1個元素,且已經排序完成。而A[1]是A[1..n]中的最小元素,因此,整個數組就排序好了,這意味著演算法是正確的。
1.2 演算法分析
BUILD-MAX-HEAP(A)的時間代價是O(n)
MAX-HEAPIFY(A, 1)的時間代價是O(lgn)
所以時間代價的上界是O(nlgn)