http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.htmlhtml
堆排序ios
堆排序是利用堆的性質進行的一種選擇排序。下面先討論一下堆。數組
1.堆測試
堆其實是一棵徹底二叉樹,其任何一非葉節點知足性質:ui
Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]或者Key[i]>=Key[2i+1]&&key>=key[2i+2]spa
即任何一非葉節點的關鍵字不大於或者不小於其左右孩子節點的關鍵字。3d
堆分爲大頂堆和小頂堆,知足Key[i]>=Key[2i+1]&&key>=key[2i+2]稱爲大頂堆,知足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]稱爲小頂堆。由上述性質可知大頂堆的堆頂的關鍵字確定是全部關鍵字中最大的,小頂堆的堆頂的關鍵字是全部關鍵字中最小的。code
2.堆排序的思想htm
利用大頂堆(小頂堆)堆頂記錄的是最大關鍵字(最小關鍵字)這一特性,使得每次從無序中選擇最大記錄(最小記錄)變得簡單。blog
其基本思想爲(大頂堆):
1)將初始待排序關鍵字序列(R1,R2....Rn)構建成大頂堆,此堆爲初始的無序區;
2)將堆頂元素R[1]與最後一個元素R[n]交換,此時獲得新的無序區(R1,R2,......Rn-1)和新的有序區(Rn),且知足R[1,2...n-1]<=R[n];
3)因爲交換後新的堆頂R[1]可能違反堆的性質,所以須要對當前無序區(R1,R2,......Rn-1)調整爲新堆,而後再次將R[1]與無序區最後一個元素交換,獲得新的無序區(R1,R2....Rn-2)和新的有序區(Rn-1,Rn)。不斷重複此過程直到有序區的元素個數爲n-1,則整個排序過程完成。
操做過程以下:
1)初始化堆:將R[1..n]構造爲堆;
2)將當前無序區的堆頂元素R[1]同該區間的最後一個記錄交換,而後將新的無序區調整爲新的堆。
所以對於堆排序,最重要的兩個操做就是構造初始堆和調整堆,其實構造初始堆事實上也是調整堆的過程,只不過構造初始堆是對全部的非葉節點都進行調整。
下面舉例說明:
給定一個整形數組a[]={16,7,3,20,17,8},對其進行堆排序。
首先根據該數組元素構建一個徹底二叉樹,獲得
20和16交換後致使16不知足堆的性質,所以需從新調整
這樣就獲得了初始堆。
此時3位於堆頂不滿堆的性質,則需調整繼續調整
/*堆排序(大頂堆) 2011.9.14*/
#include <iostream>
#include<algorithm>
using namespace std;
void HeapAdjust(int *a,int i,int size) //調整堆
{
int lchild=2*i; //i的左孩子節點序號
int rchild=2*i+1; //i的右孩子節點序號
int max=i; //臨時變量
if(i<=size/2) //若是i是葉節點就不用進行調整
{
if(lchild<=size&&a[lchild]>a[max])
{
max=lchild;
}
if(rchild<=size&&a[rchild]>a[max])
{
max=rchild;
}
if(max!=i)
{
swap(a[i],a[max]);
HeapAdjust(a,max,size); //避免調整以後以max爲父節點的子樹不是堆
}
}
}
void BuildHeap(int *a,int size) //創建堆
{
int i;
for(i=size/2;i>=1;i--) //非葉節點最大序號值爲size/2
{
HeapAdjust(a,i,size);
}
}
void HeapSort(int *a,int size) //堆排序
{
int i;
BuildHeap(a,size);
for(i=size;i>=1;i--)
{
//cout<<a[1]<<" ";
swap(a[1],a[i]); //交換堆頂和最後一個元素,即每次將剩餘元素中的最大者放到最後面
//BuildHeap(a,i-1); //將餘下元素從新創建爲大頂堆
HeapAdjust(a,1,i-1); //從新調整堆頂節點成爲大頂堆
}
}
int main(int argc, char *argv[])
{
//int a[]={0,16,20,3,11,17,8};
int a[100];
int size;
while(scanf("%d",&size)==1&&size>0)
{
int i;
for(i=1;i<=size;i++)
cin>>a[i];
HeapSort(a,size);
for(i=1;i<=size;i++)
cout<<a[i]<<"";
cout<<endl;
}
return 0;
}