L3-016 二叉搜索树的结构(30 分)
二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。(摘自百度百科)
给定一系列互不相等的整数,将它们顺次插入一棵初始为空的二叉搜索树,然后对结果树的结构进行描述。你需要能判断给定的描述是否正确。例如将{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
分析:这一题要判断的东西多,但其实每一个子功能并不复杂,考察快速建树的技能。
#include<iostream>
#include <cstdio>
#include <malloc.h>
using namespace std;
typedef struct t{
int data;
struct t * left;
struct t * right;
}Btree;
int level;
int n,a[101];
bool flag;
Btree * look;
int fl(int a,Btree *t,int l)
{
if (t != NULL) {//看在第几层
if(a<t->data)fl(a,t->left,l+1);
if(a>t->data)fl(a,t->right,l+1);
if(t->data==a)
level=l;
}
return level;
}
void fd(int a,Btree * t)
{
if (t != NULL) {
if(a<t->data)fd(a,t->left);
if(a>t->data)fd(a,t->right);
if(t->data==a)
look=t;
}
}
void create(Btree * &tree,int x)//没有返回值,指针传引用过来
{
if(tree==NULL){//如果该位置是空节点,插入.
tree=(Btree *)malloc(sizeof(Btree));
tree->left=NULL;
tree->right=NULL;
tree->data=x;
return;
}
if(x>tree->data)//如果大于该结点往右子树上递归。
create(tree->right,x);
else
create(tree->left,x);
}
void issb(int a,int b,Btree * t)
{
if (t != NULL&&t->left&&t->right) { //搜索整棵树看是否,ab为t的子兄弟结点
if(t->left->data==a&&t->right->data==b||t->left->data==b&&t->right->data==a)
flag=true;
issb(a,b,t->left);
issb(a,b,t->right);
}
}
int isparent(int a,int b,Btree * t)
{
fd(a,t);//找到a结点的指针
Btree * c=look;
if((c->left&&c->left->data==b)||(c->right&&c->right->data==b))//如果儿子里有b
return 1;
return 0;
}
int islc(int a,int b,Btree * t)
{
fd(b,t);
Btree * c=look;
if(c->left&&c->left->data==a)
return 1;
return 0;
}
int isrc(int a,int b,Btree * t)
{
fd(b,t);
Btree * c=look;
if(c->right&&c->right->data==a)
return 1;
return 0;
}
int find2(int x)//该点是否存在
{
for(int i=0;i<n;i++)
if(a[i]==x)
return 1;
return 0;
}
int main()
{
freopen("L3-016. 二叉搜索树的结构.txt","r",stdin);
string s;
Btree *p=NULL;
cin>>n;
for(int i=0;i<n;i++){
int num;
cin>>num;
a[i]=num;
create(p,num);//插入结点
}
int m;
cin>>m;
for(int i=0;i<m;i++){
int a;
string is;
cin>>a>>is;
if(is=="is"){
cin>>is>>is;
if(is=="root")//"A is the root",即"A是树的根";
printf("%s\n",find2(a)&&p->data==a?"Yes":"No");
else{
int b;
if(is=="parent"){
cin>>is>>b;//"A is the parent of B",即"A是B的双亲结点";
printf("%s\n",find2(a)&&find2(b)&&isparent(a,b,p)==1?"Yes":"No");
}
else{
string k;
cin>>k>>k>>b;
if(is[0]=='l')//"A is the left child of B",即"A是B的左孩子";
printf("%s\n",find2(a)&&find2(b)&&islc(a,b,p)==1?"Yes":"No");
else // "A is the right child of B",即"A是B的右孩子";
printf("%s\n",find2(a)&&find2(b)&&isrc(a,b,p)==1?"Yes":"No");
}
}
}
else{
int b;
cin>>b>>is>>is;
if(is[0]=='s'){
flag=false;
issb(a,b,p);//"A and B are siblings",即"A和B是兄弟结点";
printf("%s\n",find2(a)&&find2(b)&&flag==true?"Yes":"No");
}
else{//"A and B are on the same level",即"A和B在同一层上"。
printf("%s\n",find2(a)&&find2(b)&&fl(b,p,0)==fl(a,p,0)?"Yes":"No");
cin>>is>>is>>is;
}
}
}
return 0;
}