1159 Structure of a Binary Tree (30 分)

抽象
在这里插入图片描述

学会:
1.sscanf;
2.str.find();
3.给两个序列怎么建树(我只会一个序列建树(BST));

PAT题目就全部链表建树吧,要的东西用map vector存。

0.main

int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		int x;
		cin>>x;
		post.push_back(x);
	}
	for(int i=0;i<n;i++){
		int x;
		cin>>x;
		in.push_back(x);
	}
	root=build(n-1,0,n-1);
	bfs(root,0);
	cin>>m;
	getchar();
	for(int i=0;i<m;i++){
		string a;
		getline(cin,a);
		if(jude(a))
			printf("Yes\n");	
		else
			printf("No\n");
	}
	return 0;
}

1.建树。

node* build(int root ,int l,int r){		//看别人都用4参数,其实没必要post的边界,只要inorder的边界
	if(l>r) return NULL;
	int i=0;
	while(i<r && in[i]!=post[root]) i++;
	node *now=new node();
	now->val=post[root];
	now->l=build(root-(r-i)-1,l,i-1);
	now->r=build(root-1,i+1,r);
	return now;
}

2.建树就老老实实建树,然后用bfs根据题目来,我是边写边看的。有一点注意,
本题额外的存储,1 map的<节点值,深度> same level
2 map的<节点值,节点值> siblings
3 map的<节点值,节点> parent child
针对不同的情况用map存,第三个不建议用数组,因为涉及左右节点的精确判断,会多敲些代码。

3.bfs,就朴素的bfs,没什么亮点。

void bfs(node*root,int de){
	queue<node*> q;
	root->deep=de;
	q.push(root);
	while(!q.empty()){
		node *now=q.front();
		q.pop();
		mp[now->val]=now;
		d[now->val]=now->deep;
		int cnt=0;
		if(now->l){
			cnt++; 
			now->l->deep=now->deep+1;
			q.push(now->l);
		}
		if(now->r){
			cnt++;
			now->r->deep=now->deep+1;
			q.push(now->r);			
		}
		if(now->l && now->r){
			bro[now->l->val]=now->r->val;
			bro[now->r->val]=now->l->val;
		}
		if(cnt==1) isf=0;
	}
}

4.判断。大头部分,
sscanf(字符串,格式,&a,&b,…)

		sscanf(s.c_str(),"%d and %d are on the same level",&a,&b);

我真的第一次用。
find()

if(s.find("root")!=-1){	
			sscanf(s.c_str(),"%d is the root",&a);
			return a==(root->val);
		}
int jude(string s){
	if(s[0]=='I'){
		return isf==1;
	}
	else{
		int a,b;
		if(s.find("root")!=-1){
			sscanf(s.c_str(),"%d is the root",&a);
			return a==(root->val);
		}
		else if(s.find("siblings")!=-1){
			sscanf(s.c_str(),"%d and %d are siblings",&a,&b);
			return bro[a]==b;
		}
		else if(s.find("level")!=-1){
			sscanf(s.c_str(),"%d and %d are on the same level",&a,&b);
			return d[a]==d[b];
		}
		else if(s.find("left")!=-1){			
			sscanf(s.c_str(),"%d is the left child of %d",&a,&b);
			if(mp[b]->l && mp[b]->l->val==a)				//这里
			return 1;
		}
		else if(s.find("right")!=-1){
			sscanf(s.c_str(),"%d is the right child of %d",&a,&b);
			if(mp[b]->r && mp[b]->r->val==a)				//这里
			return 1;
		}
		else{
			sscanf(s.c_str(),"%d is the parent of %d",&a,&b);
			if((mp[a]->l && mp[a]->l->val==b)||(mp[a]->r && mp[a]->r->val==b))		//这里,
																					//这三个地方必须严格按照判断节点判断值,特别是最后个地方,我还想合起来写,结果就   段错误   。
			return 1;
		}
		return 0;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值