算法導論學習-heapsort


heap的定義:如果數組a[1,....n]滿足:a[i]>a[2*i] && a[i]>a[2*i+1]1<=i<=n/2,那么就是一個heap,而且是max-heap

heap有兩種,max-heap 和 min-heap,其中min-heap的性質與上面所述相反,即 a[i]<a[2*i] && a[i]<a[2*i+1].

這里以max-heap為例說明heap的三種基本操作,即Max-Heap-Maintenance, Build-Max-Heap, HeapSort.

1. Max-Heap-Maintenance

input:數組A和下標indice(i)  output:維護以 i 為根的子樹的max-heap性質。

Max-Heap-Maintenance的偽代碼如下

 

以一個例圖來解釋上述程序的運行過程:

 a) 圖為heap的初始狀態,現在執行程序Max-Heap-Maintenance(A,2)。node 2的值為4,比左孩子值14小,所以把A[2] 和 A[4]進行交換,這里雖然右孩子值為7,也比A[2]要大,但我們要找兩個孩子中值最大的孩子,並且將父節點和它交換。交換完畢后,從被交換的孩子節點的位置出發,圖中是A[4],見圖b),然后在該節點上重復上述操作,直至該節點是葉子節點,如圖C),則終止程序。

2. Build-Max-Heap

 

因為每進行一次Max-Heap-Maintenance(i)操作,實際上都是建立以 i 為根節點的最大heap的一棵子樹。所以我們自底向上建立最大heap,只有這樣才能保證建立的heap具有max-heap性質。

3. Heap-Sort

首先先建立max-heap,但我們仍不能夠根據max-heap得到排序結果,因為max-heap只能保證根節點值大於孩子節點的值,並沒有孩子節點之間的大小關系比較。具體做法看偽代碼+樣例分析圖。

最后貼上C++實現代碼:

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 int a[101];
 5 int array_size,heap_size;
 6 int left(int i){
 7     return 2*i;
 8 }
 9 int right(int i){
10     return 2*i+1;
11 } 
12 void Max_Heap_Maintenance(int i){
13     int l, r, largest=-1;
14     l=left(i);
15     r=right(i);
16     if(l>heap_size||r>heap_size) return;
17     if(l<=heap_size&&a[l]>a[i]){
18         largest=l;
19     }
20     else largest=i;
21     if(r<=heap_size&&a[r]>a[largest]){
22         largest=r;
23     }
24     if(largest!=i){
25         int tmp=a[largest];
26         a[largest]=a[i];
27         a[i]=tmp;
28         Max_Heap_Maintenance(largest);
29     }    
30 }
31 void Build_Max_Heap(){
32     heap_size=array_size;
33     for(int i=array_size/2;i>=1;i--){
34         Max_Heap_Maintenance(i);
35     }
36 }
37 void Heap_Sort(){
38     Build_Max_Heap();
39     for(int i=array_size;i>=2;i--){
40         int tmp=a[i];
41         a[i]=a[1];
42         a[1]=tmp;
43         heap_size--;
44         Max_Heap_Maintenance(1);
45     }
46     int tmp=a[2];
47     a[2]=a[1];
48     a[1]=tmp;
49 }
50 int main(){
51     while(scanf("%d",&array_size)!=EOF){
52         for(int i=1;i<=array_size;i++){
53             scanf("%d",&a[i]);
54         }
55         Heap_Sort();
56         for(int i=1;i<=array_size;i++){
57             printf("%d ",a[i]);
58         }printf("\n");
59     }
60     return 0;
61 }
Code-HeapSort

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM