排序演算法之堆排序

2021-07-22 16:34:22 字數 1487 閱讀 3556

同樣的先上這張圖

下面看一種較為複雜的選擇排序 ——堆排序:

首先來看一下什麼是堆,堆用乙個一維的陣列模擬二叉樹的結構,即堆陣列的第乙個元素為第

二、第三個元素的父結點,即第i(i從0開始)個元素是第2i+1和第2i+2個元素的父結點,由此我們可以得到每乙個結點的父結點,設為j。由 n=2j+1(n為奇數)和 n=2j+2(n為偶數)得 j=(n-1)/2(是奇數);j=(n-2)/2 (n是偶數)。

知道了堆的定義之後我們用堆來實現排序,首先我們構建乙個小頂堆(父結點比子結點小),然後每次彈出根結點,重新調整堆,直到堆為空。

因此,實現堆排序需解決兩個問題:

1. 如何將n 個待排序的數建成堆;

2. 輸出堆頂元素後,怎樣調整剩餘n-1 個元素,使其成為乙個新堆。

對於第乙個問題,我們知道最後乙個結點的父結點是floor( (n-1) / 2),以只需要對以該結點為根結點的樹進行篩選,使其成為小頂堆。之後向前依次對各結點為根的子樹進行篩選,使之成為堆,直到根結點。

如圖建堆初始過程:無序序列:(49,38,65,97,76,13,27,49)

對於第二個問題,

調整小頂堆的方法:

1)設有m 個元素的堆,輸出堆頂元素後,剩下m-1 個元素。將堆底元素送入堆頂((最後乙個元素與堆頂進行交換),堆被破壞,其原因僅是根結點不滿足堆的性質。

2)將根結點與左、右子樹中較小元素的進行交換。

3)若與左子樹交換:如果左子樹堆被破壞,即左子樹的根結點不滿足堆的性質,則重複方法 (2).

4)若與右子樹交換,如果右子樹堆被破壞,即右子樹的根結點不滿足堆的性質。則重複方法 (2).

5)繼續對不滿足堆性質的子樹進行上述交換操作,直到葉子結點,堆被建成。

* 堆排序

* 先建立乙個小頂堆

* 然後彈出堆頂元素,再調整堆為小頂堆

* o(nlogn)

* o(1)

* 不穩定

*/template void sorthelp::heapsort(t l, int length)

} //彈出堆頂元素放到最後

for (int i = length - 1; i > 0; i--)}}}

設樹深度為k,

而建堆時的比較次數不超過4n 次,因此堆排序最壞情況下,時間複雜度也為:o(nlogn )。

由於不需要額外的輔助空間,其空間複雜度為o(1),即常量複雜度。

由於堆在篩選過程中可能打亂順序,所以堆排序不是穩定的。

排序演算法之堆排序

前言 今天我來介紹下堆排序,在寫堆排序 之前,我們要知道堆的概念!堆的定義 n個關鍵字序列kl,k2,kn稱為 heap 當且僅當該序列滿足如下性質 簡稱為堆性質 1 ki k 2i 且ki k 2i 1 1 i n 當然,這是小根堆,大根堆則換成 號。k i 相當於二叉樹的非葉子結點,k 2i 則...

排序演算法之堆排序

堆排序演算法是選擇排序的一種,該演算法只是通過堆,最大堆 或者最小堆選擇出乙個待排序序列中的最大值,或者最小值。要想實現堆排序演算法,就需要構建什麼堆,這裡也最小堆為例。說明什麼是堆,怎麼構建乙個堆。假設待排序序列為a n 為乙個陣列。陣列的長度為n 陣列下標為 0,1,2,i,2i,2i 1 n ...

排序演算法之堆排序

宣告 本博文 為樓主親自編寫並測試,其它內容引用至我一直很崇拜的牛人morewindows。他對排序演算法的講解通俗易懂,給人一種耳目一新的感覺。堆排序與快速排序 歸併排序 一樣都是時間複雜度為o n logn 的幾種常見排序方法。最小堆的講解以及最小堆元素的插入和刪除參見最小堆操作。以下繼續引用以...