title : 堆 date : 2021-8-3 tags : ACM,資料結構
什麼是堆
堆是一棵具有特定性質的二叉樹,堆的基本要求是堆中所有結點的值必須大於等於(或小於等於)其孩子結點的值,這也稱為堆的性質。堆還有另一個性質,就是當h>0時,所有葉子結點都處於第h或h-1層,也就是說,堆應該是一棵完全二叉樹。
堆的型別
大頂堆:顧名思義大的元素在頂部
小頂堆:顧名思義小的元素在頂部
堆的操作
上浮節點
void checkup(int node) //與父節點比較向上更新
{
if (node <= 1)
{
return; //已經達到堆頂
}
if (tree[node]<tree[node >> 1]) //該節點比父節點要小
{
swap(tree[node], tree[node >> 1]); //交換兩者
checkup(node >> 1); //繼續上浮
}
}
下沉節點
void checkdown(int node) //向下更新二叉堆
{
if (node > num)
{
return; //已經無法下沉
}
if (tree[node] < tree[node << 1] && tree[node] < tree[node << 1 | 1])
{
return; //沒有比子節點小則返回
}
if (tree[node << 1] < tree[node << 1 | 1]) //左兒子小於右兒子
{
swap(tree[node], tree[node << 1]); //交換左兒子
if (node * 2 < num)
{
checkdown(node << 1); //繼續下沉
}
}
else //右兒子小於左兒子
{
swap(tree[node], tree[node << 1 | 1]);
if (node * 2 + 1 < num)
{
checkdown(node << 1 | 1);
}
}
}
插入節點
void push(long long val) //插入val
{
tree[++num] = val; //先插入到最後的位置
checkup(num); //對他進行上浮操作
}
刪除節點
void pop() //刪除最小的數,即tree[1]
{
tree[1] = tree[num]; //首先讓最後的元素移動到堆頂
tree[num] = inf; //原來的位置不再有任何元素
num--;
checkdown(1); //對堆頂進行下沉操作
}
構建二叉堆
把一個無序的完全二叉樹調整為二叉堆,只需讓所有非葉子節點依次下沉。
參考資料
https://blog.csdn.net/qq_41900081/article/details/86670001