堆排序(實現c++)
阿新 • • 發佈:2019-08-07
堆可以看作是一個完全二叉樹,分為大頂堆和小頂堆,本文我們以大頂堆為例來實現堆排序。
(1)建堆
先把給定的序列轉換成一棵完全二叉樹,然後逐步對其調整使其每個結點的值都大於其兩個子結點的值,因此我們需要從第一個非葉結點開始逐步向前調整(葉結點不存在子結點比其大的狀況,所以從非葉結點往前調整),假設一共有n個元素,那麼第一個調整的結點為n/2。
(2)交換並調整
每次調整後將第一個最大的結點跟尾結點換位,則每一輪都是最大的在末尾,然後再次堆第一個結點進行調整,使得成為大頂堆,然後再次交換並調整,以此往復。
void shift(int a[], int low, int high){ //對陣列中處於low位的結點進行一次向下調整 int temp = a[low]; int i = low, j = 2*i; //i為待調整結點,j為i的子結點, while(j <= high){ //若i沒有子結點則跳出迴圈 if(a[j] < a[j+1]) //跟子結點中較大的比較 j++; if(a[j] > temp){ //大頂堆子結點較大就跟雙親結點換位 a[i] = a[j]; i = j; j = 2 * i; } else break; } a[i] = temp; }
void heapSort(int a[], int n){ //陣列下標從1開始 int i; int temp; for (i = n/2; i >= 1; --i) //建堆,從第一個非頁結點即n/2開始逐步往前調整 { shift(a, i, n); } for (i = n; i >= 2; ++i)//調整的第二個結點就行了,後面n-1個結點有序,且較大 { tmep = a[1];//每次調整後將第一個最大的跟尾結點換位,則每一輪都是最大的在末尾 a[1] = a[i]; a[i] = temp; shift(a, 1, n-1); } }
&n