二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。(摘自百度百科)
给定一系列互不相等的整数,将它们顺次插入一棵初始为空的二叉搜索树,然后对结果树的结构进行描述。你需要能判断给定的描述是否正确。例如将{ 2 4 1 3 0 }插入后,得到一棵二叉搜索树,则陈述句如“2是树的根”、“1和4是兄弟结点”、“3和0在同一层上”(指自顶向下的深度相同)、“2是4的双亲结点”、“3是4的左孩子”都是正确的;而“4是2的左孩子”、“1和3是兄弟结点”都是不正确的。
输入格式:
输入在第一行给出一个正整数N(≤100),随后一行给出N个互不相同的整数,数字间以空格分隔,要求将之顺次插入一棵初始为空的二叉搜索树。之后给出一个正整数M(≤100),随后M行,每行给出一句待判断的陈述句。陈述句有以下6种:
A is the root,即"A是树的根";
A and B are siblings,即"A和B是兄弟结点";
A is the parent of B,即"A是B的双亲结点";
A is the left child of B,即"A是B的左孩子";
A is the right child of B,即"A是B的右孩子";
A and B are on the same level,即"A和B在同一层上"。
题目保证所有给定的整数都在整型范围内。
输出格式:
对每句陈述,如果正确则输出Yes,否则输出No,每句占一行。
输入样例:
5
2 4 1 3 0
8
2 is the root
1 and 4 are siblings
3 and 0 are on the same level
2 is the parent of 4
3 is the left child of 4
1 is the right child of 2
4 and 0 are on the same level
100 is the right child of 3
输出样例:
Yes
Yes
Yes
Yes
Yes
No
No
No
思路
昨天选拔赛忘了C++链表怎么建了,没申请空间,整了半天编译错误,唉
代码
#include<bits/stdc++.h>
using namespace std;
typedef struct stu *Tree;
struct stu{
int x=0;
Tree r=NULL;
Tree l=NULL;
int num;
};
Tree Build(int x,Tree T,int num){
if(T==NULL){
Tree T1=new stu;
T1->x=x;
T1->num=num;
T=T1;
}else{
if(x>T->x){
T->r=Build(x,T->r,num+1);
}else if(x<T->x){
T->l=Build(x,T->l,num+1);
}
}
return T;
}
Tree fun(Tree T,int x){
while(T&&T->x!=x){
if(x>T->x) T=T->r;
else T=T->l;
}
return T;
}
int main(){
int n,x;
cin>>n;
Tree T=NULL;
for(int i=0;i<n;i++){
cin>>x;
T=Build(x,T,1);
}
int m,a,b;
string s,s1;
cin>>m;
getchar();
for(int i=0;i<m;i++){
int flag=0;
getline(cin,s);
if(s.find("root")!=s.npos){
s1=s.substr(0,s.find(" "));
a=stoi(s1);
if(T&&T->x==a) flag=1;
}else if(s.find("siblings")!=s.npos){
s1=s.substr(0,s.find(" "));
a=stoi(s1);
s1=s.substr(s.find("and")+4,s.find(" are")-s.find("and")-4);
b=stoi(s1);
Tree T2,T1=T;
while(T1->x!=a&&T1){
T2=T1;
if(a>T1->x) T1=T1->r;
else T1=T1->l;
}
if(T1&&T2->r&&T2->l&&(T2->r->x==a&&T2->l->x==b||T2->l->x==a&&T2->r->x==b))
flag=1;
}
else if(s.find("parent")!=s.npos){
s1=s.substr(0,s.find(" "));
a=stoi(s1);
s1=s.substr(s.find("of")+3);
b=stoi(s1);
Tree T1=fun(T,a);
if(T1&&(T1->l&&T1->l->x==b||T1->r&&T1->r->x==b)) flag=1;
}
else if(s.find("left")!=s.npos){
s1=s.substr(0,s.find(" "));
a=stoi(s1);
s1=s.substr(s.find("of")+3);
b=stoi(s1);
Tree T1=fun(T,b);
if(T1&&T1->l&&T1->l->x==a) flag=1;
}
else if(s.find("right")!=s.npos){
s1=s.substr(0,s.find(" "));
a=stoi(s1);
s1=s.substr(s.find("of")+3);
b=stoi(s1);
Tree T1=fun(T,b);
if(T1&&T1->r&&T1->r->x==a) flag=1;
}
else if(s.find("level")!=s.npos){//同一层
s1=s.substr(0,s.find(" "));
a=stoi(s1);
s1=s.substr(s.find("and")+4,s.find(" are")-s.find("and")-4);
b=stoi(s1);
Tree T1=fun(T,a);
Tree T2=fun(T,b);
if(T1&&T2&&T1->num==T2->num) flag=1;
}
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
网上搜到了更简便的写法
【CCCC】L3-016 二叉搜索树的结构 (30分),,手动建堆(二叉搜索树节点询问),map写法
代码
#include<bits/stdc++.h>
using namespace std;
struct node{
int l=-1;
int r=-1;
int fa=-1;//双亲节点
int h;//高度
};
map<int,node> Tree;
void insert(int root,int h,int x){
if(root==-1) return;
int rr=x<root?Tree[root].l:Tree[root].r;
if(rr==-1){
if(x<root) Tree[root].l=x;
else Tree[root].r=x;
Tree[x].fa=root;
Tree[x].h=h;
}
else insert(rr,h+1,x);
}
int Judge(int root,int a,int b,string s1){
if(s1=="root") return a==root;//这个判断必须在find前面,因为该树可能只有一个节点
if(Tree.find(a)==Tree.end()||Tree.find(b)==Tree.end()) return 0;
else if(s1=="siblings") return Tree[a].fa==Tree[b].fa;
else if(s1=="parent") return Tree[b].fa==a;
else if(s1=="level") return Tree[a].h==Tree[b].h;
else if(s1=="left") return Tree[b].l==a;
else if(s1=="right") return Tree[b].r==a;
}
int main(){
int n,root,t;
cin>>n>>root;
for(int i=2;i<=n;i++){
cin>>t;
insert(root,1,t);
}
int m,a=0,b=0;
cin>>m;
for(int i=0;i<m;i++){
string s,s1;
cin>>a;
getchar();
getline(cin,s);
if(s.find("root")!=s.npos) s1="root";
else if(s.find("siblings")!=s.npos){
s1=s.substr(4,s.find("are")-4);
b=stoi(s1);
s1="siblings";
}
else if(s.find("parent")!=s.npos){
s1=s.substr(s.find("of")+3);
b=stoi(s1);
s1="parent";
}
else if(s.find("left")!=s.npos){
s1=s.substr(s.find("of")+3);
b=stoi(s1);
s1="left";
}
else if(s.find("right")!=s.npos){
s1=s.substr(s.find("of")+3);
b=stoi(s1);
s1="right";
}
else if(s.find("level")!=s.npos){
s1=s.substr(4,s.find("are")-4);
b=stoi(s1);
s1="level";
}
if(Judge(root,a,b,s1)) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}