八大排序演算法(4) 堆排序

2021-08-03 06:38:04 字數 2008 閱讀 8816

是對簡單選擇排序的改進,是一種樹形結構的排序。

利用堆的特性,快速選擇出序列中的最大最小元素。

堆的定義:

用樹表示更加直觀:

即:父節點 不大於/不小於 其子節點的完全二叉樹。

降序時稱為 大堆頂,公升序時稱為 小堆頂。

這樣的堆,其堆頂就是整個序列中最大/最小的元素。

不斷的取出堆頂、將剩下序列重組成堆的過程就叫堆排序。

樹採用順序儲存:,

序列是樹的順序儲存,因此 節點、父、子 在序列中的位置為 i,2i,2i+1, 反映到序列中的 index 為 i - 1, 2*i-1, 2*i。

1. 初始化時將整個序列轉換成堆  

2. 取出堆頂後,將剩下的元素快速組成堆

先說第二點的演算法思路:

1. 取出堆頂後 i 後,將堆底元素取出補為堆頂

2. 檢查到堆被破壞,將 堆頂 與其子節點中小的元素交換

3. 對交換後的子樹重複2

示例圖:

再說第一點的演算法思路:

1. 假設 長度 n 的 序列 k 為堆

2. 最後乙個節點是 節點 n/2 的子節點,那麼從 n/2 開始向上篩選

3. 從 父子節點 中選舉最小的為 父節點

4. 對交換後的子節點 重複 3,直到葉子節點

5. 檢查下乙個 n/2 - 1 ,重複 3, 直到 0

示例圖:

* 修復堆

* * 從 父子 節點中選舉最小的為父節點。

* 如果最小的不是父節點的話,那麼交換過的子節點也需要檢查。

*/void adjustheap(int *l, int n, int topindex, int adjustindex)

// 跟 右子節點比較,替換 小的 index

if (rcindex < n && l[minindex] > l[rcindex])

// 如果小的index 不是 堆頂的話,那麼換頂,然後檢查子堆

if ( minindex != adjustindex )}/*

* 建立堆

* * 1、假設 長度 n 的 序列 k 為堆

* 2、最後乙個節點為 n / 2 的子節點,從 n / 2 開始向上篩選

* 3、從 父子節點中選舉最小的為 父節點

* 4、檢查下乙個 n / 2 - 1 ,重複 3, 直到 0

*/void buildheap(int *l, int n)

if ( 2*i < n && l[min] > l[rc])

if ( min != i-1 )

}}int main() ;

int n = 9;

printlist(list, n);

// 建立小堆頂

buildheap(list, n);

printlist(list, n);

printf("*****=\n");

// 建好堆後,初始堆頂就是最小的

for (int i = n - 1; i > 0; i--)

system("pause");

return

0;}

八大排序演算法 堆排序

排序,分為內部排序和外部排序,內部排序是指將資料記錄在記憶體中進行排序,而外部排序因排序的資料很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存,所以稱之為外部排序,我們這裡講的八大排序全部屬於內部排序。堆排序 heapsort 是指利用堆積樹 堆 這種資料結構所設計的一種排序演算法,它是選...

八大排序 堆排序

堆排序 利用大頂堆 小頂堆 堆頂記錄的是最大關鍵字 最小關鍵字 這一特性,使得每次從無序中選擇最大記錄 最小記錄 變得簡單。其基本思想為 大頂堆 1 將初始待排序關鍵字序列 r1,r2 rn 構建成大頂堆,此堆為初始的無須區 2 將堆頂元素r 1 與最後乙個元素r n 交換,此時得到新的無序區 r1...

八大排序(四) 堆排序

堆是具有以下性質的完全二叉樹 每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆 每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆 如下圖所示 對堆中的結點按層進行編號,將這種邏輯結構對映到陣列中就是下面這個樣子 以上陣列從邏輯上講就是乙個堆結構,用簡單的公式來描述一下堆的定義就是 大頂堆...