七大排序之堆排序

<HeapSort>
簡單選擇排序的改進:減少第i趟排序比較的次數。
對排序的關鍵:建堆和調整堆。
建堆的過程:
第1趟將索引0至n-1處的全部數據建大頂堆,就可以選出這組數據的最大值。將該堆的根節點跟這組數據的最后1個節點交換,就使得這組數據中最大排在了最后;
第2趟將索引0至n-2處的全部數據建大頂堆,就可以選出這組數據的最大值。將該堆的根節點與這組數據的倒數第2個節點交換,就使的這組數據中最大值排在了倒數第2位;
......
索引0至n-k處的全部數據建大頂堆,就可以選出這組數據的最大值。將該堆的根節點與這組數據的倒數第k個節點交換,就使的這組數據中最大值排在了倒數第k位。
其實整個堆排序過程中, 我們只需重復做兩件事:
建堆(初始化+調整堆, 時間復雜度為O(n));
拿堆的根節點和最后一個節點交換(siftdown, 時間復雜度為O(nlog n) )
因而堆排序整體的時間復雜度為O(n
log n)。
偽代碼:

//對下標為i的節點來說
parent(i) return i/2;
left(i) return 2*i;
right(i) return 2*i+1;
void adjust(int *a, int size,int index)
{
    int left = 2*index;
    int right = 2*index+1;
    int parent = index/2;
    int maxIndex = index;
    if(left<size && a[left]>a[maxIndex]) maxIndex=left;
    if(right<size && a[right]>a[maxIndex]) maxIndex=right;//maxIndex是3個數中最大數的下標
    if(index != maxIndex)
    {
        swap(a[index],a[maxIndex]);
        adjust(a,size,maxIndex); //遞歸調整其它不滿足堆性質的部分
    }

}

void HeapSort(int *a,int size)
{
    for(int i=size/2-1;i>=0;i--) // 對每一個非葉結點進行堆調整(從最后一個非葉結點開始)
    {
        adjust(a,size,i);
    }
    for(int i = size-1;i>=1;i--)
    {
        swap(a[0],a[i]);//將當前最大的放置到數組末尾;
        adjust(a,i,0);
    }
}
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 排序的基本概念 在計算機程序開發過程中,經常需要一組數據元素(或記錄)按某個關鍵字進行排序,排序完成的序列可用于快...
    Jack921閱讀 1,458評論 1 4
  • 概述 因為健忘,加上對各種排序算法理解不深刻,過段時間面對排序就蒙了。所以決定對我們常見的這幾種排序算法進行統一總...
    清風之心閱讀 717評論 0 1
  • 難過的時候看看天 開心的時候看天 想念的時候看天 抱怨的時候看天 幸福的時候看天 煩惱的時候看天 天空,有一種玄絲...
    文墨糯糯閱讀 244評論 0 0
  • 虎妞兒又搬家了,被某人開口說中,要把書吧的箱子住個遍…… 中午回到書吧,收拾食盆兒的時候出奇得安靜...
    自由行走的卡兒媽閱讀 242評論 4 1
  • 姓名:李俊秀 公司:寧波大發化纖有限公司 期數:六項精進259期學員 組別:感謝一組 【日精進打卡第17天】 【知...
    花語花香9閱讀 204評論 0 0