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; }