P5076 普通二叉树
P5076 普通二叉树
P5076 【深基16.例7】普通二叉树(简化版) - 洛谷
题目含义:
-
Search(x):查询x,并计算x的排名——严格小于x的个数+1 -
SearchXth():查询排名为x的数(一定有解) -
SearchPredecessor(x):找x的前驱 -
SearchSuccessor(x):找x的后继 -
Insert(x):插入x“本题的数据保证插入前 x 不在集合中”
核心:
数据结构:
struct BSTNode{
int data;
int size;
BSTNode *lchild,*rchild;
};
找前驱和后缀:
- 类比二分答案代码
- root负责寻找目标节点,pre或suc则始终在合法区间,
- pre∈{小于x的所有可能节点}∪{nullptr},suc∈{大于x的所有可能节点}∪
- 注意
- 初始值,pre=nullptr,suc=nullptr
- 相等的情况:pre和suc均不应该指向值相等的点
- 代码含义:
BSTNode* FindPredecessor(BSTNode* root,int val)
{
BSTNode* pre=nullptr;
while(root){
if(root->data<val){//root及其左子树较小
pre=root; //但属于合法区间
root=root->rchild;//root尝试最大化
}
else if(root->data>=val){//root及其右子树较大
root=root->lchild;//尝试缩小root到合法区间
}
}
return pre;
}
验证:
5
/ \
3 8
/ \ \
1 4 10
/
9
对应样例:
14
5 5
5 3
5 1
5 4
5 8
5 10
5 9
3 8
3 9
4 5
4 3
4 4
4 10
4 8
代码:
struct BSTNode{
int data;
int size;
BSTNode *lchild,*rchild;
};
int q,opt,x;
//查找x,并计算严格小于x的个数(cnt)
BSTNode* Search(BSTNode* root,int val,int& cnt)
{
if(!root) return root;
if(root->data>val){
return Search(root->lchild,val,cnt);
}
else if(root->data<val){
cnt+=1;//root自身
if(root->lchild) cnt+=root->lchild->size;//左子树结点数
return Search(root->rchild,val,cnt);
}
else{
if(root->lchild) cnt+=root->lchild->size;
return root;
}
}
//插入值val的节点
void Insert(BSTNode* &root,int val)
{
if(!root){
root=new BSTNode;
root->data=val;
root->size=1;//包括自己
root->lchild=nullptr;
root->rchild=nullptr;
}
else if(root->data>val){
Insert(root->lchild,val);
root->size++;
}
else if(root->data<val){
Insert(root->rchild,val);
root->size++;
}
//else root->data==val
}
//查询排名为x的数
void SearchXth(BSTNode* root,int rk)
{
if(!root) return;
int leftsize=0;
if(root->lchild) leftsize=root->lchild->size;
if(leftsize>=rk){
SearchXth(root->lchild,rk);
}
else if(leftsize+1==rk){
cout<<root->data<<"\n";
}
else{
SearchXth(root->rchild,rk-leftsize-1);
}
}
//无论val是否存在,找到小于val的最大节点并返回
BSTNode* FindPredecessor(BSTNode* root,int val)
{
BSTNode* pre=nullptr;
while(root){
if(root->data<val){
pre=root;
root=root->rchild;
}
else if(root->data>=val){
root=root->lchild;
}
}
return pre;
}
//无论val是否存在,找到大于vak的最大节点并返回
BSTNode* FindSuccessor(BSTNode* root,int val)
{
BSTNode* post=nullptr;
while(root){
if(root->data<=val){
root=root->rchild;
}
else if(root->data>val){
post=root;
root=root->lchild;
}
}
return post;
}
int main()
{
int rk,cnt;
bool flag;
BSTNode *root=nullptr;
BSTNode *px=nullptr,*pre=nullptr,*suc=nullptr;
cin>>q;
for(int i=1;i<=q;++i){
flag=false;
cin>>opt>>x;
if(opt==1){
rk=0;
px=Search(root,x,rk);
cout<<rk+1<<"\n";
}
else if(opt==2){
SearchXth(root,x);
}
else if(opt==3){
pre=FindPredecessor(root,x);
if(pre) cout<<pre->data<<"\n";
else cout<<-2147483647<<"\n";
}
else if(opt==4){
suc=FindSuccessor(root,x);
if(suc) cout<<suc->data<<"\n";
else cout<<2147483647<<"\n";
}
else{
Insert(root,x);
}
}
return 0;
}

浙公网安备 33010602011771号