例题6-7 UVa122 Trees on the level(树&&队列BFS&&sscanf字符串转整数)
题意:
看白书
要点:
这题还真难,有很多不知道的特殊函数知识不说,还有很多C++的容器。结点最多256个,要考虑最差的情况就是排成一条链,这样深度是256,如果用数组会爆炸,所以用动态分配。
sscanf()的这种读取字符串转换为整数的方法比较特殊,适用面比较窄:sscanf(&s[0],"%d",&i),如果要能提取字符串中的数字,首先这个字符串必须满足第一个是数字,后面可以是字符,但后面如果出现数字同样不能提取,例如:815aff15gfd,只能提取到815,如果是ad158gdg这种,可以将&s[0]改为&s[2],这样相当于从第3个开始是数字。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
char s[1000];
bool failed; //判断输入的数据是否有误的标记
vector<int > ans;
struct node
{
bool have_value;
int value;
node *left,*right;
node() :have_value(false), left(NULL), right(NULL) {} //C++中特有的结构体构造函数,相当于调用时都初始化一次
};
node *root;
node* newnode()
{
return new node(); //其他功能跟malloc差不多,但malloc不调用类型中的构造函数,所以只能用new
} //new自动返回对应node的指针
void addnode(int v, char *s)
{
int n = strlen(s);
node* u = root;
for (int i = 0; i < n; i++)
{
if (s[i] == 'L')
{
if (u->left == NULL)
u->left= newnode();
u = u->left;
}
else if(s[i]=='R')
{
if (u->right == NULL)
u->right = newnode();
u = u->right;
}
}
if (u->have_value) failed = true; //已经赋值过,说明输入有误
u->value = v;
u->have_value = true;
}
bool read_input()
{
failed = false;
root = newnode();
while(1)
{
if (scanf("%s", s)!=1)
return false;
if (!strcmp(s, "()"))
break;
int v;
sscanf(&s[1], "%d", &v); //特殊,第一个字符可以是非数字,第二个开始必须为数字
addnode(v, strchr(s, ',') + 1);//strchr在s中寻找第一个“,”,并返回指向它地址的指针
}
return true;
}
bool bfs(vector<int>& ans)//vector为不定长数组,不用像一般数组那样先指定大小
{
queue<node*> q;//可以用队列实现二叉树的层次遍历,即宽度优先遍历BFS
ans.clear();
q.push(root);
while (!q.empty())
{
node *u = q.front(); q.pop();
if (!u->have_value) return false;
ans.push_back(u->value); //在不定长数组当前最后加一个数
if (u->left != NULL) q.push(u->left);
if (u->right != NULL) q.push(u->right);
}
return true;
}
void pri_out()
{
int t = 0;
for (int i = 0; i<ans.size(); i++) //只要像普通数组那样输出就行
{
if (i) printf(" ");
printf("%d", ans[i]);
}
printf("\n");
ans.clear();
}
int main()
{
while (read_input())
{
if (failed || !bfs(ans)) printf("not complete\n");
else pri_out();
}
return 0;
}