---
tags: codebook
---
{%hackmd theme-dark %}
# heapsort
堆積排序
## 概念
1. 製作最大堆
2. 持續維護堆的性質,並將最大值逐個推到陣列末端
## 範例
0. 初始堆
```graphviz
digraph heap{
node[fontcolor = white;color=white]
edge[color=white]
bgcolor = "#343434"
9 -> {8 7}
7->{6 3}
8->{5 4}
5->{2 0}
4->{1}
}
```
1. 將根和最後一個葉對換,並刪除最後一個葉
```graphviz
digraph heap{
node[fontcolor = white;color=white]
edge[color=white]
bgcolor = "#343434"
1[color=turquoise]
1-> {8 7}
7->{6 3}
8->{5 4}
5->{2 0}
4->{9[color=turquoise;style=dashed]}
}
```
```arr:[9]```
2. 維護堆性質,1和8換
```graphviz
digraph heap{
node[fontcolor = white;color=white]
edge[color=white]
bgcolor = "#343434"
8[color=red]
8-> {1[color=red] 7}
7->{6 3}
1->{5 4}
5->{2 0}
}
```
```arr:[9]```
3. 維護堆性質,1和5換
```graphviz
digraph heap{
node[fontcolor = white;color=white]
edge[color=white]
bgcolor = "#343434"
8-> {5[color=red] 7}
7->{6 3}
5->{1[color=red] 4}
1->{2 0}
}
```
```arr:[9]```
4. 維護堆性質,1和2換
```graphviz
digraph heap{
node[fontcolor = white;color=white]
edge[color=white]
bgcolor = "#343434"
8-> {5 7}
7->{6 3}
5->{2[color=red] 4}
2->{1[color=red] 0}
}
```
```arr:[9]```
5~. 再次重複步驟1直到堆大小為0
```graphviz
digraph heap{
node[fontcolor = white;color=white]
edge[color=white]
bgcolor = "#343434"
0[color=turquoise]
0-> {5 7}
7->{6 3}
5->{2 4}
2->{1 8[color=turquoise;style=dashed]}
}
```
```arr:[8|9]```
```graphviz
digraph heap{
node[fontcolor = white;color=white]
edge[color=white]
bgcolor = "#343434"
0[color=red;label=7]
0-> {5 7[color=red;label=0]}
7->{6 3}
5->{2 4}
2->1
}
```
```arr:[8|9]```
```graphviz
digraph heap{
node[fontcolor = white;color=white]
edge[color=white]
bgcolor = "#343434"
7
7-> {5 6[color=red]}
6->{0[color=red] 3}
5->{2 4}
2->1
}
```
```arr:[8|9]```
```graphviz
digraph heap{
node[fontcolor = white;color=white]
edge[color=white]
bgcolor = "#343434"
1[color=turquoise]
1-> {5 6}
6->{0 3}
5->{2 4}
2->{7[color=turquoise;style=dashed]}
}
```
```arr:[7|8|9]```
以下類推
## 範例程式碼
```cpp=
#include<iostream>
#include<vector>
using namespace std;
void heapify(vector<int>& v, size_t size, size_t cur) {
size_t maxpos = cur, left = (cur << 1) + 1, right = (cur << 1) + 2;
if (left < size && v[left] > v[maxpos])
maxpos = left;
if (right < size && v[right] > v[maxpos])
maxpos = right;
if (maxpos != cur)
swap(v[cur], v[maxpos]), heapify(v, size, maxpos);
}
void heapsort(vector<int>& v) {
for (size_t i = v.size() / 2; i; i--)
heapify(v, v.size(), i - 1);
for (size_t i = v.size(); i; i--)
swap(v[0], v[i - 1]), heapify(v, i - 1, 0);
}
int main() {
vector<int> v{1, 5, 4, 2, 0, 3, 6, 7, 8, 9};
heapsort(v);
for (const auto& i : v)
cout << i << ' ';
return 0;
}
```