ACM學習筆記:二叉堆

LINNO發表於2021-08-17
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

https://blog.csdn.net/qq_39445165/article/details/84932335

相關文章