算法導論筆記-第六章-堆排序

6.1 堆
堆是一個數組,也可以被看作近似的完全二叉樹。樹上的每一個結點都對應數組中的一個元素。除了最底層,該樹是完全充滿的。
可以用某一數組代表堆,其中包含兩個屬性:
A.length 代表給出的數組元素的數目
A.heap-size 代表又多少個堆元素存儲在該數組中

(樹性質:
前提:近似完全二叉樹,從左到右排序,i爲某結點編號
其父結點爲:i/2
左孩子:2i
右孩子:2i+1

高度:該結點到葉結點最長簡單路徑上邊的數目
(n個元的的堆,高度爲[lg2](向下取整))

葉結點下標:n表示數組存儲的n個元素時,葉節點下標分別爲[n/2]+1,[n/2]+2,[n/2]+3.....

最大堆:某個結點的值最大與其父結點相同。 //A[PARENT(i)] >=A[i]
最小堆:某個結點的值最小與其父結點相同。 //A[PARENT(i)] <=A[i]

6.2 維護堆的性質
MAX-HEAPIFY過程:時間複雜度爲O(lg n) 維護堆的關鍵。
僞代碼
MAX-HEAPIFY(A,i)
l=LEFT(i)
r=RIGHT(i)
if l<=A.heap-size and A[l]>A[i]
largest = l
else
if r<=A.heap-size and A[r]>A[i]
largest = r
if largest != i
exchange A[i] with A[largest]
MAX-HEAPIFY(A,largest)
C實現:
int RIGHT(int i) {
return 2 * i + 1;
}
int LEFT(int i){
return 2* i;
}


void MAX_HEAPIFY(int A[], int i)
{
int A_heap_size = 10;
int l = LEFT(i);
int r = RIGHT(i);
int largest = i;
if (l<=A_heap_size && A[l]>A[i]) {
largest = l;
}
if (r<=A_heap_size && A[r]>A[largest] ){
largest = r;
}
if (largest != i) {
int temp=A[i];
A[i] = A[largest];
A[largest] = temp;
MAX_HEAPIFY(A,largest);
}
}
BUILD-MAX-HEAP過程:線性時間複雜度,功能時從無序的輸入數據數組中構造一個最大堆。
僞代碼:
BUILD-MAX-HEAP(A)
A.heap-size = A.length
for i = [A.length/2] downto 1
MAX-HEAPIFY(A,i)dd
C實現:
void BUILD_MAX_HEAP(int A[],int length) {
int A_heap_size = length;
int i = length;
for (i; i > 0; i--) {
MAX_HEAPIFY(A, i, A_heap_size);
}
}
HEAPSORT過程:時間複雜度爲O(lg n),功能時堆一個數組進行原址排序。
僞代碼:
HEAPSORT(A)
BUILD-MAX-HEAP(A)
for i=A.length downto 2
exchangeA[1] with A[i]
A_heap-size--
MAX-HEAPIFY(A,1)
C語言實現:void HEAPSORT(int A[],int length) {
int A_heap_size = length;
int i = length;
BUILD_MAX_HEAP(A, A_heap_size);
for (; i > 1; i--){
int temp = A[1];
A[1] = A[i];
A[i] = temp;
A_heap_size--;
MAX_HEAPIFY(A, 1, A_heap_size);
}
}
MAX-HEAP-INSERT,HEAP-EXTRACT-MAX,HEAP-INCREASE-KEY,HEAP-MAXIMUM過程:
時間複雜度O(lg n),功能時利用堆實現一個優先隊列。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章