【排序演算法7】堆排序
阿新 • • 發佈:2018-12-02
此排序演算法完全是看著MoreWindows大神的部落格一邊看一邊體會一邊跟著敲出來的,在這裡還是非常感謝他。
部落格地址https://blog.csdn.net/MoreWindows/article/details/6709644
上述地址對堆排序講的很細緻,這裡就不講了。但是不知道為什麼那篇部落格中評論裡會這麼多人說有錯誤。
#include <stdio.h> #include <Windows.h> void Swap(int *a,int *b) { int temp = *a; *a = *b; *b = temp; } void Print(int a[],int n) { for( int i = 0 ; i < n ; ++i ) { printf("%d ",a[i]); } printf("\n"); } // 新加入i節點,其父節點為(i-1)/2 void MinHeapFixup(int a[] ,int i) { int j,temp; temp = a[i]; j = (i - 1) / 2; //父節點 while( j >= 0 && i != 0 ) { if(j >= 0 && i != 0) { break; } a[i] = temp; i = j; //向父節點遞迴,當前這個i表示父節點 j = (i - 1) / 2; } a[i] = temp; } //堆的插入 void MinHeapAddNumber(int a[],int n,int nNum) { a[n] = nNum; MinHeapFixup(a,n); } //調整堆 void MinHeapFixdown(int a[],int i,int n) { int j,temp; temp = a[i]; j = 2 * i + 1; while( j < n ) { if( j + 1 < n && a[j + 1] < a[j] ) { ++j; } if( a[j] >= temp ) { break; } a[i] = a[j]; i = j; j = 2 * i + 1; } a[i] = temp; } //在最小堆中刪除數 void MinHeapDeleteNumber( int a[],int n ) { Swap( &a[0] ,&a[n - 1] ); MinHeapFixdown(a,0,n - 1); Print(a,n); } //建立最小堆 void MakeMinHeap(int a[],int n) { //葉子節點不用排 for( int i = n / 2 - 1 ; i >= 0 ; --i) { MinHeapFixdown(a,i,n); printf("下沉的節點%d. ",i); Print(a,n); } } void MinheapsortTodescendarray(int a[],int n) { MakeMinHeap(a,n); for( int i = n ; i >= 1 ; --i ) { MinHeapDeleteNumber(a,i); } } int main() { int a[10] = {9,12,17,30,50,20,60,65,4,49}; MinheapsortTodescendarray(a,10); for( int i = 0 ; i < 10 ; ++i ) { printf("%d ",a[i]); } printf("\n"); system("pause"); return 0; }
列印結果如下圖,最小堆實現的降序排序