1159 Structure of a Binary Tree

Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, a binary tree can be uniquely determined.

Now given a sequence of statements about the structure of the resulting tree, you are supposed to tell if they are correct or not. A statment is one of the following:

  • A is the root
  • A and B are siblings
  • A is the parent of B
  • A is the left child of B
  • A is the right child of B
  • A and B are on the same level
  • It is a full tree

Note:

  • Two nodes are on the same level, means that they have the same depth.
  • A full binary tree is a tree in which every node other than the
    leaves has two children.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are no more than 10
3
and are separated by a space.

Then another positive integer M (≤30) is given, followed by M lines of statements. It is guaranteed that both A and B in the statements are in the tree.

Output Specification:

For each statement, print in a line Yes if it is correct, or No if not.

Sample Input:

9
16 7 11 32 28 2 23 8 15
16 23 7 32 11 2 28 15 8
7
15 is the root
8 and 2 are siblings
32 is the parent of 11
23 is the left child of 16
28 is the right child of 2
7 and 11 are on the same level
It is a full tree

Sample Output:

Yes
No
Yes
No
Yes
Yes
Yes

思路

第一步:根据中序遍历和后序遍历递归建树,建树的过程中注意存一下每个孩子节点的父亲节点和每个父亲节点的孩子节点
第二步:根据称述作相应判断,这里用到了字符串的操作,sscanf可以从字符串中读信息出来然后存起来,把信息抠出来后简单判断即可。判断是不是满二叉树只需在dfs的过程中判断是不是这个节点是不是左右孩子节点都有或者都没有即可

cpp代码

#include<iostream>
#include<unordered_map>
using namespace std;
const int N=40;
unordered_map<int,int> depth,pos,parent,l,r;
int post[N],in[N];
int n,m;
bool full_tree;
int root;
int build(int inl,int inr,int posl,int posr,int deep){
	int root=post[posr];
	int k=pos[root];
	depth[root]=deep;
	if(k>inl){
		int t=build(inl,k-1,posl,k-1-inl+posl,deep+1);
		l[root]=t;
		parent[t]=root;
	}
	if(k<inr){
		int t=build(k+1,inr,k-1-inl+posl+1,posr-1,deep+1);
		r[root]=t;
		parent[t]=root;
	}
	return root;
}
bool dfs(int u){
	if((!r.count(u)&&l.count(u))||(r.count(u)&&!l.count(u)))
		return false;
	bool res1=true,res2=true;
	if(l.count(u))res1=dfs(l[u]);
	if(r.count(u))res2=dfs(r[u]);
	return res1&&res2;
}
bool check(string s){
	if(s.find("root")!=-1){
		int t;
		sscanf(s.c_str(),"%d is the root",&t);
		if(t==root)return true;
		else return false;
	}
	else if(s.find("siblings")!=-1){
		int a,b;
		sscanf(s.c_str(),"%d and %d are siblings",&a,&b);
		if(parent.count(a)&&parent.count(b)){
			if(parent[a]==parent[b])return true;
		}
		return false;
	}
	else if(s.find("parent")!=-1){
		int a,b;
		sscanf(s.c_str(),"%d is the parent of %d",&a,&b);
		if(parent.count(b)){
			if(parent[b]==a)return true;
		}
		return false;
	}
	else if(s.find("left")!=-1){
		int a,b;
		sscanf(s.c_str(),"%d is the left child of %d",&a,&b);
		if(l.count(b)){
			if(l[b]==a)return true;
		}
		return false;
	}
	else if(s.find("right")!=-1){
		int a,b;
		sscanf(s.c_str(),"%d is the right child of %d",&a,&b);
		if(r.count(b)){
			if(r[b]==a)return true;
		}
		return false;
	}
	else if(s.find("level")!=-1){
		int a,b;
		sscanf(s.c_str(),"%d and %d are on the same level",&a,&b);
		if(depth[a]==depth[b])return true;
		else return false;
	}
	else if(s.find("full")!=-1){
		if(full_tree)return true;
		return false;
	}
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++)cin>>post[i];
	for(int i=0;i<n;i++){
		cin>>in[i];
		pos[in[i]]=i;
	}	
	root=build(0,n-1,0,n-1,0);
	full_tree=dfs(root);//判断是不是满二叉树 
	int m;
	cin>>m;
	getchar();//吸收回车 
	while(m--){
		string s;
		getline(cin,s);
		if(check(s))puts("Yes");
		else puts("No");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值