heap sort 堆積排序 介紹與實作原理
堆積排序是透過最大堆積樹來進行排序,其實作與原理如下
主要核心是要讓 root 大於左右子樹,由於我們每次都能夠找出 root,且必定大於左右子樹,因此我們只需要將 root 提出來,再讓左右子樹中的最大值替補 root,依序遞迴擊可。
- 我們用一維陣列來表達我們的二元樹
- 其中 index 0 一定是二元樹中最大的數字
- 透過遞迴,參數: i
- 以當前 i 節點為 root,L、R 分別是左右子樹
- 如果左子樹數值比 i 數值還要大,那就讓 i 與左子樹交換
- 如果右子樹數值比 i 數值還要大,那就讓 i 與右子樹交換
- 如果先前有進行交換的動作,那我們就讓與 i 交換的子樹再重新進行遞迴
我們主要是維護二元堆積樹的 root 最大,如果 root 與其他數值有做交換,那我們必須讓 root 往下至其適合的位置,適合的位置:左右子樹都沒有比他還大,root 本身比左右子樹更大
時間複查度為 O(nlogn),在某些演算法中會用到堆積排序,因此算是篇重要的排序演算法之一。
參考來源
HeapSort by geeksforgeeks
heap sort 堆積排序 程式碼說明與應用
透過程式碼來進行說明相信會更好理解,以下我們示範從小到大排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| #include <iostream> #include <bits/stdc++.h>
using namespace std; int num[] = {4,96,1546,13,48,34,77,48,31}; int num_size;
void output(){ for(int i = 0 ; i < num_size ; i++) cout << num[i] << ' ' ; cout << '\n' ; }
void heapify(int n, int i){ int root = i; int L = 2 * i; int R = 2 * i + 1;
if(L < n && num[L] > num[root]) root = L; if(R < n && num[R] > num[root]) root = R;
if(root != i){ swap(num[root], num[i]); heapify(n, root); } }
void heap_sort(){ for(int i = num_size/2; i >= 0; i--) heapify(num_size, i);
for(int i = num_size-1; i >= 0; i--){ swap(num[0], num[i]); heapify(i, 0); } }
int main() { num_size = sizeof(num) / sizeof(num[0]); heap_sort(); output(); return 0; }
|
心得
由於 C++ 已經有很多 sort 套件了,因此我在高中學會後我就再也沒有去複習這些知識。
剛好現在上課有用到那就來複習,順便把它寫出邏輯八!
程式執行結果
