先看下堆的概念:堆是一種數據結構,邏輯上是一種完全的二叉樹,在存儲上是數組對象。
堆分爲小頂堆和大頂堆,顧名思義:小頂堆是指頂部的元素是最小的,大頂堆是指頂部的元素師最大的。
這樣只要我們能夠得到這樣的堆,每次將頂部的元素和數列的最後一個元素進行交換,然後再對剩下的元素進行建堆,接着以此類推這樣的做法,便可以得到排好的數列了。
根據上面所述,堆排序的關鍵是:建堆。建堆也分爲調堆和建堆過程;
調堆的過程是:比較一個節點和他的子節點的大小,將最小的或者最大的數和父節點交換,交換後的子節點再接着當做父節點做同樣的比較,知道不需要交換爲止;代碼如下:
void _adjust_heap(int *A,int size,int element)
{
int left=2*element+1;
int right=left+1;
int min=0;
while(left<size)
{
min=left;
if(right<size)
{
if(A[min]>A[right]) min=right;
}
if(A[element]>A[min]) swap(A[element],A[min]);
else break;
element=min;
left=2*element+1;
right=left+1;
}
}</span>
建堆的過程是:對堆的非葉子節點進行調堆,就完成了建堆的過程。
void _build_heap(int *B,int size)
{
for(int i=size/2-1;i>=0;i--)
{
_adjust_heap(B,size,i);
}
}</span>
排序的過程:對數組進行建堆,每次將第一個元素和最後一個元素交換,然後數組的規模減一,再建堆,直到只剩下一個元素爲止。
void _sort(int *A,int size)
{
int length=size;
for(;length>=1;length--)
{
_build_heap(A,length);
swap(A[length-1],A[0]);
}
}</span>
編寫程序進行測試:
void main()
{
int ia[]={0,3,2,6,2,9,2,3,1};
int size=sizeof(ia)/sizeof(int);
_sort(ia,size);
for(int i=0;i<size;i++)
{
cout<<ia[i]<<endl;
}
}</span>
測試結果爲: