使用最大堆來排序
什麼是最大堆呢,就是,有一個完全二叉樹,其中兒子節點的值永遠小於等於父節點的值。
堆排序中關鍵的幾個步驟:
- max_heapify:功能是維護最大堆的性質,執行這一步時,要保證當前節點的兩個子樹都是最大堆
如何維護堆的性質呢?
一句話,就是保證當前節點大於等於兩個兒子節點。如果不滿足,找到兒子節點中大的那個,跟父親結點交換,然後對子樹繼續維護堆的性質,用遞歸調用就完事啦。
- build_max_heap:功能是從無序的輸入數組中構造一個最大堆
構造最大堆,要用自底向上的方法。大小爲n的數組,子數組[n/2,....n]都是葉子節點。從序號n/2 downto 1對數組中的元素調用一次max_heapify。
- heapsort:堆排序
先構造堆,然後讓a[1]和數組最後一個元素A[n]交換,並去掉節點n,接着調用max_heapify,重複上述過程n-1次,就完成了排序。build_max_heap的時間複雜度是O(n),n-1次max_heapify,每次是O(lgn),所以heapsort的時間複雜度是O(nlgn)
貼程序
#include<iostream>
using namespace std;
void max_heapify(int *a, int i,int size)
{
int left = i * 2;
int right = i * 2 + 1;
int largest = i;
if (left <= size&&a[left] > a[i])
largest = left;
if (right <= size&&a[right] > a[largest])
largest = right;
if (largest != i)
{
int temp = a[i];
a[i] = a[largest];
a[largest] = temp;
max_heapify(a, largest, size);
}
}
void build_max_heap(int *a,int size)
{
int i = size / 2;
for (i; i >= 1; i--)
{
max_heapify(a,i, size);
}
}
void heapsort(int *a,int size)
{
build_max_heap(a, size);
for (int i = 1; i <= 10; i++)
cout << a[i] << ",";
int i = size;
for (i; i >= 2; i--)
{
int temp = a[1];
a[1] = a[i];
a[i] = temp;
size--;
max_heapify(a,1,size);
}
}
int main()
{
int a[17] = { 0,4,1,3,2,16,9,10,14,8,7};
heapsort(a, 10);
return 0;
}