以任意顺序给出一棵二叉树的节点,格式如: (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读入节点的位置.