L3-016 二叉搜索树的结构(模拟)

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


猜你喜欢

转载自blog.csdn.net/zpjlkjxy/article/details/80730211