[UVA122]Trees on the level

以任意顺序给出一棵二叉树的节点,格式如: (5,LLRL), 数字表示该节点的值.

要求输出一棵树中从一个叶子走到根节点的取到最小权值和的那个叶子节点,假如有多个叶子节点能取到最小的权值,则输出叶子权值本身最小的那个叶子.题目保证了每个节点的权值都是不同的.假如一组输入,存在一个节点被赋值超过1次或者没被赋值,则输出"not complete".每组输入用()作为该组数据的终结符

题目其实没啥说的,主要还是输入输出比较麻烦,只要把这颗树读进去,还是非常简单的.

照着刘汝佳默写出了人生中第一个bfs,代码如下.

#include<bits/stdc++.h>
#define rep(i,a,n) for(i=a;i<=n;i++)
#define per(i,a,n) for(i=a;i>=n;i--)
#define maxn 256+20
using namespace std;
bool failed;
vector <int> ans;
bool bfs();
bool read_tree();
void addnode(int v,char* str);
struct node{
	node* l;node* r;
	int val;
	bool valued;
};
node* root;
node* newnode(){
	return new node();
}
bool bfs(){
	ans.clear();
	queue <node*> f;
	node* tmp;
	tmp=root;f.push(tmp);
	while(!f.empty()){
		tmp=f.front();
		f.pop();
		if(tmp->l!=NULL) f.push(tmp->l);
		if(tmp->r!=NULL) f.push(tmp->r);
		if(tmp->valued==false) return false;
		ans.push_back(tmp->val);
	}
	return true;
}
char s[maxn];

bool read_tree(){
	failed=false;
	root=newnode();
	scanf("%s",s);
	if(strlen(s)==0)return false;
	for(;strcmp(s,"()")!=0;scanf("%s",s)){
		int v;
		sscanf(&s[1],"%d",&v);
		addnode(v,strchr(s,',')+1);
	}
	return true;
}
void addnode(int v,char* str){
	node* tmp;
	tmp=root;
	int len=strlen(str);
	int i;
	rep(i,0,len-1){
		if(str[i]=='L'){
			if(tmp->l==NULL) tmp->l=newnode();
			tmp=tmp->l;
		}
		else if(str[i]=='R'){
			if(tmp->r==NULL) tmp->r=newnode();
			tmp=tmp->r;
		}
	}
	if(tmp->valued)failed=true;
	tmp->val=v;
	tmp->valued=true;
}
int main(){
	while(read_tree()){
		if(!bfs())failed=true;
		if(failed)printf("not complete\n");
		else{
			int i,l=ans.size();
			rep(i,0,l-1){
				if(i!=l-1)printf("%d ",ans[i]);
				else{
					printf("%d",ans[i]);
				}
			}
			printf("\n");
		}
	}
}

其中结构体指针也是这学期刚在数据结构课上看的,就是用 p->l,p->r就可以从根往叶子节点走.

然后代买里面有3个函数值得讲一讲.

首先是strcmp(char*p,char*q)假如两个数组相等,则返回0,所以题目里面用(!strcmp(p,"()")return ;

然后就是sscanf(&s[1],"%d",&v);用&s[1]是为了把(给略过,用这个可以直接读到里面的数字,赋值给变量v,这个用法直接背下来吧,今晚再慢慢看具体实现.

最后是strchr()用来找某个字符在某数组中出现的第一个index.这样就可以直接让addnode读入节点的位置.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值