標籤:
圖例參考http://www.cnblogs.com/mengdd/archive/2012/11/30/2796845.html
原文參考http://blog.csdn.net/eseaqyq/article/details/7497575
//以下是針對堆進行調整
void HeapAjust(int data[],int i,int length)
{
int nChild;
int nTemp;
for(nTemp=data[i];2*i+1<length;i=nChild)
{
nChild=2*i+1;
if(nChild<length-1&&data[nChild+1]>data[nChild])//比較哪個孩子比自己大,如果是右孩子的話,就要將nChild++;
{
nChild++;
}
if(nTemp<data[nChild])//如果比自己的最大的孩子小,就交換
{
data[i]=data[nChild];
data[nChild]=nTemp;
}
else//如果比最大的孩子還大,就不交換
break;
}
}
//堆排序
void HeapSort(int data[],int length)
{
for(int i=(length>>1)-1;i>=0;i--)//注意這個地方:i=(length>>1)-1,加上括弧,原因:優先順序的問題
{
HeapAjust(data,i,length);//初始化一個堆
}
for(int j=length-1;j>0;--j)
{
int temp=data[j];
data[j]=data[0];
data[0]=temp;
HeapAjust(data,0,j);
}
}
上面主要是功能函數,主函數大家搞定啦!我調試通過了已經!
堆排序的時間複雜度為O(nlogn),最壞的情況也是這個時間複雜度,空間複雜度是O(1)。但是堆排序是不穩定的!
在面試過程中,很多時候都會用到堆排序,比如下面的題目都是堆排序的典型題目:
1.給你100w個資料求最大的10個元素。這個時候我們可以使用小頂堆!這個是為什麼呢!
2.給你100w個資料求最小的10個元素。這個時候我們可以使用大頂堆!這個是為什麼呢!
相信會有很多同學會問出上面的兩個疑問,答案其實很簡單,在求最大的元素的時候,我們建立一個有10個元素的小頂堆,那麼堆頂元素肯定是最小的,然後拿剩餘的元素和堆頂進行比較,如果比堆頂大,就替換這個元素,然後調整堆,調整完之後堆頂依然是10個元素中最小的,依次比較剩餘的元素。
堆排序與直接插入排序的區別
直接選擇排序中,為了從R[1..n]中選出關鍵字最小的記錄,必須進行n-1次比較,然後在R[2..n]中選出關鍵字最小的記錄,又需要做n-2次比 較。事實上,後面的n-2次比較中,有許多比較可能在前面的n-1次比較中已經做過,但由於前一趟排序時未保留這些比較結果,所以後一趟排序時又重複執行 了這些比較操作。 堆排序可通過樹形結構儲存部分比較結果,可減少比較次數。
【轉】堆排序