是對簡單選擇排序的改進,是一種樹形結構的排序。
利用堆的特性,快速選擇出序列中的最大最小元素。
堆的定義:
用樹表示更加直觀:
即:父節點 不大於/不小於 其子節點的完全二叉樹。
降序時稱為 大堆頂,公升序時稱為 小堆頂。
這樣的堆,其堆頂就是整個序列中最大/最小的元素。
不斷的取出堆頂、將剩下序列重組成堆的過程就叫堆排序。
樹採用順序儲存:,
序列是樹的順序儲存,因此 節點、父、子 在序列中的位置為 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...
八大排序(四) 堆排序
堆是具有以下性質的完全二叉樹 每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆 每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆 如下圖所示 對堆中的結點按層進行編號,將這種邏輯結構對映到陣列中就是下面這個樣子 以上陣列從邏輯上講就是乙個堆結構,用簡單的公式來描述一下堆的定義就是 大頂堆...