關於堆排序 參考自演算法導論

2021-06-06 19:52:00 字數 2249 閱讀 5482

堆排序是一種很有用的排序演算法,有用的並不是在排序上的用處,而是那個大根堆和小根堆的建立,在平時的運用中,舉足輕重!乙個最有用的例項就是作業系統的程序的最大優先權排程演算法。從很多程序中,找到優先順序最大的程序,然後分配cpu資源。堆排序的主要步驟也就是建立堆。一旦最大堆(最小堆)建立好了,排序也是十分簡單的事情了。下面的我們全部以大根堆來做講解

堆是一種資料結構,可以理解成為一種完全二叉樹,但是有個苛刻的要求:除了根節點外的所有節點的父節點的值要大於該節點的值。其實就是所有父節點的值要大於子節點的值。比如下圖描述的結構:

我們有了這種結構之後,就可以確定從堆頂所得到的值一定是最大值,我們可以把最大值換出來,然後再次把我們的結構打亂了的堆重新組合成為標準的大根堆,這就是整個堆排序的過程。堆排序的主要時間也是花在元件堆和重建堆上。

組建堆的過程:

說到最重要的乙個子環節:保持最大堆 max_heapify

說明:這個操作可以使堆中的某個節點在其子樹滿足堆性質的前提下,讓它及其子樹滿足堆的性質。

下圖的堆中,發現第二個節點不滿足堆的性質,且它的子節點對應的子樹都是滿足堆的性質的,所以進行如下操作,讓其重新調整為大根堆

max_heapify:

1)對比節點與其兩個子節點,選出值最大的乙個節點,如果當前節點不是最大,就把子節點中最大的乙個和當前節點進行交換操作

2)由於第乙個操作可能讓交換節點的那棵子樹失去堆的性質,所以對交換後的節點也進行第一布操作,這是乙個遞迴的過程

以max_heapify(pos=2)為例的過程如圖:

(1、交換節點)

(2、對交換節點進行遞迴呼叫)

從上面的操作可以看出,如果我們的子樹都是符合大根堆的,則可以依從下往上的的讓整個樹都變成大根堆。由此特性,我們可以寫出讓整個樹變成大根堆堆的演算法:

build_max_heap

all)對n/2到1號節點進行max_heapify操作,讓整個樹變成大根堆。(因為在完全二叉樹中只有n/2的節點存在子樹其餘n/2是葉子)過程我就不再畫圖了。

以上兩步就是組成大根堆的所有過程了,簡單吧。接下來就是排序過程了

heap_sort

1)把最後節點和首節點進行交換,得到最大值,放到末尾。

2)從堆中去掉最後乙個節點,我們可以用heap_size來表示,heap_size減1即可。對從第乙個節點進行max_heapify操作,取得第二大的值。

3)重複1和2操作,依次得到從大到小的所有的值。直到堆只有1個元素為止

具體過程如下:(只針對heap_size為10的情況)

(1、把最後節點和首節點交換,堆大小減1)

(2、堆首節點進行max_heapify操作,重建堆)

下面我們簡單的對堆排序進行時間複雜度分析:

max_heapify的時間複雜度為o(lgn)(因為完全二叉樹樹的高度為lgn,最多隻會進行二叉樹高度次變換)

build_max_heap操作會n/2次呼叫max_heapify,則時間複雜度為o(n/2*lgn)

heap_sort操作會n次呼叫max_heap_fy,則時間複雜度為o(n*lgn)

綜合上面,時間複雜度為o(n*lgn)+o(n*lgn)=o(n*lgn)

堆排序的效率還是很高的。至少是比較類的排序演算法中最優的。

另外,很容易看出堆排序不是穩定的排序演算法,因為如果2個相同的值,不是在一棵子樹裡面,而是分開的,很可能就把後面的那個值交換到了前面。這不用多說了。

總結:堆排序的主要用處並不是光在於它的排序,而是在於堆的這個性質,最大值或者最小值永遠在第乙個,而且保持性質的所付出的時間代價很小。這樣可以做出很多有用的東西,比如優先順序佇列就是很好的乙個應用。下面附上我自己實現的堆排序的c++源**。

堆排序原始碼位址

堆排序 演算法導論

python版 1 defheapsort input 2output 3buildheap input 4print input 5while input 6i len input 1 7input 0 input i input i input 0 89 ifinput 10maxheapify...

堆排序 演算法導論

python版 1 defheapsort input 2output 3buildheap input 4print input 5while input 6i len input 1 7input 0 input i input i input 0 89 ifinput 10maxheapify...

演算法導論 堆排序

堆排序演算法 heapsort max heapify過程,其執行時間為 lg n 是保持最大堆性質的關鍵 build max heap過程,以線性時間執行,可以在無序的輸入陣列基礎上構造出最大堆 heapsort過程,執行時間 n lg n 對乙個陣列原地進行排序 heapsort過程 1 建最大...