C語言堆排序
阿新 • • 發佈:2018-12-11
%d heap alt d+ clas mage src 不用 temp
堆是一種類似二叉樹的數據結構,分為最大堆和最小堆,最大堆得定義是當前節點必須大於左右子節點,堆中所有節點都要符合這個定義。最小堆反之。這一點不同於二叉樹排序。假設有數組int a[10] = {90,45,21,43,22,77,13,89,56,84},根據最大堆來初始化數組
最大堆初始化代碼思路:用數組最後一個元素來確定最後一個子節點,根據子節點來找到其父節點。先比較左右子節點確定最大子節點,如果父節點大於則不用互換,否則父節點與最大子節點互換。然後父節點減一(利用數組的順序依次遞減來操作所有節點)。當然利用for循環來使父節點的所有子節點(包括子節點的子節點)都符合最大堆的定義。
1 voidmaxheap_sortDown(int a[],int start,int end){ 2 3 int code = start; 4 int lchild = code*2+1; 5 int temp = a[code]; 6 7 for(;lchild<=end;code = lchild,lchild = code*2+1){ 8 9 if(lchild<end && a[lchild]>a[lchild+1]) 10 lchild++; //確定最大子節點,很巧妙 11 12 if(a[code]<a[lchild]) 13 break; 14 else{ 15 a[code] = a[lchild]; 16 a[lchild] = temp; 17 } 18 19 } 20 21 } 22 23 void maxheap_sortUp(int a[],int start,int end){ 24 25 int code = start;26 int lchild = code*2+1; 27 int temp = a[code]; 28 29 for(;lchild<=end;code = lchild,lchild = code*2+1){ 30 31 if(lchild<end && a[lchild]<a[lchild+1]) 32 lchild++; //確定最大子節點,很巧妙 33 34 if(a[code]>a[lchild]) 35 break; 36 else{ 37 a[code] = a[lchild]; 38 a[lchild] = temp; 39 } 40 41 } 42 43 }
堆排序思路:把堆頂的元素與最後一個元素進行互換,互換之後在把除最後一個元素外的所有元素進行堆的定義操作,使其符合最大(小)堆。然後在互換元素,使除最後兩個元素外的所有元素進行堆的定義操作,依次進行則排序完成。
1 void maxheap_sort(int a[],int n){ 2 3 int i; 4 for(i=(n-1)/2;i>=0;i--) 5 // maxheap_sortUp(a,i,n); 6 maxheap_sortDown(a,i,n); 7 8 int temp = a[0]; 9 a[0] = a[n]; 10 a[n] = temp; 11 12 for(i=n/2-1;i>=0;i--) 13 // maxheap_sortUp(a,i,n-1); 14 maxheap_sortDown(a,i,n-1); 15 16 }
測試:
1 void main(){ 2 3 void maxheap_sort(int a[],int n); 4 void maxheap_sortUp(int a[],int start,int end); 5 6 int a[10] = {90,45,21,43,22,77,13,89,56,84}; 7 int i; 8 printf("before:"); 9 for(i=0;i<10;i++){ 10 printf("%d ",a[i]); 11 } 12 13 14 printf("\n"); 15 16 for(i=9;i>=0;i--) 17 maxheap_sort(a,i); 18 19 printf("after:"); 20 for(i=0;i<10;i++){ 21 printf("%d ",a[i]); 22 } 23 24 25 }
C語言堆排序