二叉堆、BST 与平衡树
二叉堆
一种父节点与子节点间存在特殊关系(一般为单调性)的完全二叉树,分为两种:大根堆和小根堆。前者的性质为父节点大于子节点,后者反之。
例题:
二叉堆主要支持以下操作:push
,pop
,top
和 size
。
top
不多说,返回堆顶元素即可。
int top() { return basic[1]; }
size
在 push
与 pop
操作时,使用一个变量 tot
记录当前节点数量,询问时输出 tot
即可。
int size() { return tot; }
push
往二叉堆中加入一个数时,首先加入树的数组末端,然后按照堆的性质自下而上修复二叉树,使其满足性质。
代码如下:
void push(int x) { basic[++tot] = x; modify(tot); } void modify(int x) { if (x == 1 || basic[x] > basic[x >> 1]) { return; } swap(basic[x], basic[x >> 1]); modify(x >> 1); }
- pop
将元素弹出二叉堆时,如果直接删除堆顶元素,会造成二叉树的分裂,产生大麻烦。所以,考虑将堆顶元素与堆底元素互换,再自上而下修复二叉树。
void pop() { swap(basic[1], basic[tot--]); repair(1); } void repair(int x) { if ((x << 1) > tot) return; int tar = x << 1; if ((x << 1) + 1 <= tot) { tar = (basic[x << 1] < basic[(x << 1) + 1] ? x << 1 : ((x << 1) + 1)); } if (basic[x] > basic[tar]) { swap(basic[x], basic[tar]); repair(tar); } }
与自下而上修复不同,在交换父节点与子节点的值时,策略为交换子节点中较大的一个值。
注意在 repair
时要考虑数组是否越界。
tip : 堆也可作为一种排序方式。理解了上述代码后可尝试自己写下这题。
接下来看看 STL 中的二叉堆—— priority_queue
。
操作与平常的 STL 没什么区别,注意默认大根堆,建小根堆应这样写: priority_queue<typename, vector<typename>, greater<typename> >
。
时间复杂度:push
与 pop
top
与 size
对顶堆
本质上是大根堆与小根堆的结合,用于动态维护数列中第
例题:
以 P1168 为例:
维护一个大根堆 q1.top
、q2.top
与 mid
,数列元素数量为奇数时输出 mid
即可。
二叉搜索树,
BST 的特征:
- 每个节点有唯一键值。
- BST 上以任意节点为根的子树都是 BST。
- BST 中任意节点的键值都比它左子树所有节点的键值大,比它右子树所有节点的键值小。即若用中序遍历整棵 BST 将得到的是一个有序序列。
若用给定的序列按照特征 (3) 建树,将得到的是一棵唯一的 BST。
二叉树的不平衡率
含义为其左子树或右子树的占比,取值范围为
树堆,
核心思想:用优先级(大小根堆)的思想来维护二叉树的平衡性。
根据这个思想,我们可以得到:若每个节点的键值、优先级均已确定,那么建出的二叉树的形态是唯一的。
这种把树和堆思想结合在一起的便叫「树堆」,
有旋
有旋
- 先将新节点的键值插入一个空的叶子节点。
- 为该叶子节点分配一个随机的优先度,然后按
本文作者:Cuset_VoidAldehyde
本文链接:https://www.cnblogs.com/CusetVoidAldehyde/p/18401291
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步