P5076. 普通二叉树(简化版)
考点
- 平衡树
题解
1 |
|
思路
本题是BST二叉搜索树的模板题,BST本身并没有应用空间,基本都是在用Splay、Treap、红黑树等平衡树
但手敲BST之后能对后续的平衡树学习有极大的帮助
具体实现细节见代码,主要讲一下实现难点
编程设计
查询x数的排名
每次将x和根结点root的权值比较:
如果x小于根结点root的权值,那么root及其右子树里面的所有权值都比x要大,所以递归下去查询左子树
如果x大于根结点root的权值,那么root及其左子树里面的所有权值都比x要小,所以递归下去查找右子树
并且把左子树的大小及根结点的权值出现次数纳入到答案中
如果x等于根结点root的权值,答案就等于
左子树大小 + 1
如果x不存在,返回第一个大于x的数的排名
比如数据{1, 2, 3, 3, 5}
查询0,应返回1
查询3,应返回3
查询5,应返回5
查询6,应返回6
查询排名为x的数
- 如果x小于或等于左子树的大小,则数必在左子树当中,递归查询左子树
- 如果x大于左子树的大小但小于等于
左子树大小 + 根结点权值出现次数
,说明根结点的权值就是该数 - 若大于
左子树大小 + 根结点权值出现次数
,说明在右子树;则减去左子树大小 + 根结点权值出现次数
后递归查询右子树
插入
找合适的位置插入即可,不再赘述
前驱与后继
这才是本题的核心坑点
根据题眼未找到前驱输出−2147483647,未找到后驱输出2147483647,实际上就是数列中的极小值和极大值...
找数的排名时,若该数不存在则返回第一个大于该数的排名;可以插入一个结点,令其权值设为极大值
比如{1, 2}
查找数字3,得到的结果是3,但是数列并没有3;直接插入极大值{1, 2, 2147483647}
解决
可以直接插入极小值吗?不可以!因为排名是根据左子树大小来计算的,插入极小值左子树大小会变更
考虑到唯一没有前驱的时候,就是求第一元素的前驱...所以特判即可处理
怎么求前驱呢?先求该数的排名nth
,再去找排名等于nth - 1
的数即可
题目说了,排名定义为比当前数小的数的个数+1
无论该数有多少个重复,都只取该数的第一个的排名作为答案
若该数不存在,也是返回第一个大于该数的排名
两种情况下,排名减去1都是前驱的排名
怎么求后驱呢?不能像前驱那样,会受重复数的影响
比如有例子
{1, 3, 3, 4, 4, 5}
查找3,排名为2
查找4,排名为4
如果找排名为3的数,答案是3而不是4
应该去找x + 1
的数的排名,再通过这个排名去找数,才能得到后继
还是那个性质,若该数不存在,返回第一个大于该数的排名
比如有例子
{1, 3, 3, 4, 4, 7}
要找4的后继,就先去找5的排名
但是5不存在,返回排名6
再去找排名6的数,得到真正的后继数字7