排序總結 堆排序

2021-07-28 23:18:29 字數 1658 閱讀 2033

//

// created by liyuanshuo on 2017/3/17.

//#include "heap_sort.h"

/* * 堆的定義:

* kik(2i) && k(i) > k(2i+1)

* 若以一維陣列儲存堆,則堆對應乙個完全二叉樹,並且所有的非葉節點的值均不大於(或者不小於)其子女的值

* 根節點(堆頂元素)的值是最小的(或者最大的)

* * 初始時把要排序的n個數的序列看作是一棵順序儲存的二叉樹(一維陣列儲存二叉樹),調整它們的儲存序,使之

* 成為乙個堆,將堆頂的元素輸出,便得到n個元素中最小(或最大)的元素,這時根節點的數最小(或者最大),

* 然後對後面的(n-1)個元素重新調整使之成為堆,輸出堆頂元素,得到n個元素中次小(或此大)的元素,依此類推

* 直到只有兩個節點的堆,並對它們作交換,最後得到n個節點的有序序列,這個過程稱為堆排序。

* **//*

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

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

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

* * 首先討論第二個問題:輸出堆頂元素後,對剩餘n-1元素重新建成堆的調整過程。

* 調整小頂堆的方法:

* * 1)設有m 個元素的堆,輸出堆頂元素後,剩下m-1 個元素。將堆底元素送入堆頂((最後乙個元素與堆頂進行交

* 換),堆被破壞,其原因僅是根結點不滿足堆的性質。

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

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

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

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

* * 稱這個自根結點到葉子結點的調整過程為篩選

*//*

* 再討論對n 個元素初始建堆的過程。

* * 建堆方法:對初始序列建堆的過程,就是乙個反覆進行篩選的過程

* * 1)n 個結點的完全二叉樹,則最後乙個結點是第[n/2]個結點的子樹。

* * 2)篩選從第[n/2]個結點為根的子樹開始,該子樹成為堆。

* * 3)之後向前依次對各結點為根的子樹進行篩選,使之成為堆,直到根結點。

*///從演算法描述來看,堆排序需要兩個過程,一是建立堆,二是堆頂與堆的最後乙個元素交換位置。所以堆排序有兩個

//函式組成。一是建堆的滲透函式,二是反覆呼叫滲透函式實現排序的函式。

/* * 已知h[s…m]除了h[s] 外均滿足堆的定義

* 調整h[s],使其成為大頂堆.即將對第s個結點為根的子樹篩選,

*/// h是待調整的堆陣列

// s是待調整的陣列元素的位置

// length是陣列的長度

void heap_adjust( int h, int s, int len )

else

break;

h[s] = tmp; }}

void build_heap( int h, int len )

}void heap_sort( int h, int len )

}

堆排序總結

在面試中遇到要你手寫堆排序,可以先詢問是否可以使用stl中建堆的演算法,問清楚面試官的意圖之後方可動手寫 交流最重要。heap並不屬於stl元件,是乙個幕後英雄,stl實現了最大堆,預設的元素比較方式是less,如果要使用小根堆,則將比較方式設定為greater,並用來作為priority queu...

堆排序總結

演算法基於順序儲存的 完全二叉樹 結點i的左孩子是2i 右孩子是2i 1 父節點是i 2 編號小於n 2的結點都是分支結點。大根堆 根 左 右 小根堆 根 左 右 建堆 編號 n 2的所有結點依次 下墜 調整 自底向上處理分支結點 調整規則 小元素逐層 下墜 與關鍵字更大的孩子交換 排序 將棧頂元素...

堆排序總結

堆 孩子節點總是小於 或大於 父節點的完全二叉樹 時間複雜度 o nlogn 步驟 建立堆 從完全二叉樹最後乙個內部節點向前執行堆調整 交換堆首位,堆尺寸 1 對新堆的堆首執行堆調整 重複執行第三步直到堆尺寸為0 初始化資料 var numbers for var i 0 i 20 i consol...