因为过年,这个题看了比较长的时间,但是看懂了后,感觉题目解析非常巧妙
这篇博客就记录下自己学到的东西吧!
1。在输入方面,直接开了一个bool read_input()函数,这样在输入EOF时,就返回false,所以可以在main函数里直接这样写:while(read_input()){...}。
2。在这个read_input 函数里面,用到了sscanf (&s[1]),这样就把字符串从位置1开始的字符串后面读取整数!,后面又用到了strchr(s,',')把逗号后面的字符串提取出来。
3。在结构体node里面,用了一个构造函数,不仅把have_value这个关键变量初始化为false,并且把一个node 里面的left,right也初始化到NULL,在前面学字典树时,就没这样做,而是new node后再用循环初始化NULL,这里直接用构造函数初始化,就感觉比较巧妙了。
3。遍历二叉树时用了bfs+队列,先判断left,在判断right,这样就保证了输出顺序的正确性,
4。最后释放内存用到了递归释放内存,类似于字典树。
当然,感觉写的如此精巧,最关键的还是用了自顶向下,逐步求精的方法,把每一个关键步骤分别写成了不同的函数,这样不论是查错误,还是思路,都非常的清晰明了!
代码如下 :
#include<vector>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int maxn = 100 + 10;
bool fail;
struct node{
int v;
bool have_value;
node *left,*right;
node():have_value(false),left(NULL),right(NULL){}
}*root;
void addnode(int v,char *s){
int len = strlen(s);
node *u = root;
for (int i = 0; i < len; ++i){
char ch = s[i];
if (ch == 'L'){
if (u->left == NULL)u->left = new node();
u=u->left;
}else if (ch == 'R'){
if (u->right == NULL)u->right = new node();
u=u->right;
}
}
if (u->have_value)fail=true;
u->have_value = true;
u->v=v;
}
void deal(node *u){
if (u == NULL)return;
deal(u->left);
deal(u->right);
delete u;
}
bool read_input(){
fail = false;
char s[maxn];
deal(root);
root = new node();
for (;;){
if (scanf("%s",s) != 1)return false;
if (strcmp(s,"()") == 0)break;
int v;
sscanf(&s[1],"%d",&v);
addnode(v,strchr(s,',')+1);
}
return true;
}
bool bfs(vector<int> &ans){
ans.clear();
queue<node *>q;
q.push(root);
while(!q.empty()){
node *u = q.front();q.pop();
if(u->have_value == false)return false;
ans.push_back(u->v);
if (u->left != NULL)q.push(u->left);
if (u->right != NULL)q.push(u->right);
}
return true;
}
int main()
{
while(read_input()){
vector<int>ans;
if (fail || !bfs(ans))printf("not complete\n");
else{
for (int i = 0; i < (int)ans.size(); ++i)
printf("%s%d",i?" ":"",ans[i]);
printf("\n");
}
}
return 0;
}