實現
- 初始時把要排序的n個數的序列看作是一棵順序儲存的二叉樹(一維陣列儲存二叉樹),調整它們的儲存序,使之成為一個堆,
將堆頂元素輸出,得到n 個元素中最小(或最大)的元素,這時堆的根節點的數最小(或者最大)。
然後對前面(n-1)個元素重新調整使之成為堆,輸出堆頂元素,得到n 個元素中次小(或次大)的元素。
依此類推,直到只有兩個節點的堆,並對它們作交換,最後得到有n個節點的有序序列。稱這個過程為堆排序。 - 程式碼
void adjust_heap(int a[], int n, int s){
int temp = a[s];
int child = 2*s + 1;
while(child < n){
if ((child + 1 < n -1) && (a[child] < a[child + 1])){
child +=1;
}
if (a[s] < a[child]) {
a[s] = a[child];
s = child;
child = 2 * s + 1;
}else {
break;
}
a[s] = temp;
}
}
void build_heap(int a[], int n) {
if (n < 2){
return;
}
int last_f = 0;
if (n % 2 == 0){
last_f = (n - 1) /2;
} else {
last_f = (n - 3) /2;
}
for (int i = last_f; i >=0; --i){
adjust_heap(a, n, last_f);
}
}
void heap_sort(int a[], int n) {
build_heap(a, n);
for (int i = n - 1; i >=0; --i) {
int temp = a[i];
a[i] = a[0];
a[0] = temp;
adjust_heap(a, i, 0);
print(a, n);
}
}
測試
- 程式碼
#include <iostream>
using namespace std;
void print(int a[], int num) {
for (int i = 0; i < num; ++i) {
cout << a[i] << " ";
}
cout << endl;
}
int main() {
int a[] = {7, 6, 5, 4, 3, 2, 1};
int n = sizeof(a) / sizeof(a[0]);
print(a, n);
heap_sort(a, n);
print(a, n);
cin.get();
return 0;
}
- 結果
7 6 5 4 3 2 1
6 4 5 1 3 2 7
5 4 2 1 3 6 7
4 3 2 1 5 6 7
3 1 2 4 5 6 7
2 1 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7