Trees on the level:建二叉树+广搜
题意: 告诉你一些字符串,如(12,LL)表示12在根结点的左儿子的左儿子的结点处,()表示一组字符串输入结束。输出完全指定的二叉树的顺序遍历。如果没有完全指定一棵树,(即树中的某个节点没有被赋予一个值,或者一个节点不止一次地被赋予一个值),输出“NotComplete”。
思路: 先把题目中的字符串中的整数和字母分开,建树的时候按照字母顺序找到相应结点,然后插入整数。在插数的同时要判断一下是否已经插过了。然后通过广搜按照顺序输出即可。
补充:
•substr()
截取字符串:s.substr(pos, len)
,s必须是字符串,如果是char型数组要先转换。pos表示在第几位(包括0),len表示截取长度(len如果省去,表示从pos位截取到末尾)
•strchr()函数
函数原型为:char * strchr(char * str, char/int c);
表示在字符串str中寻找字符C第一次出现的位置,并返回其位置(地址指针),若失败则返回NULL;
atoi()函数
函数原型:int atoi(const char *str);
把参数 str 所指向的字符串转换为一个int型整数
#include<bits/stdc++.h>
using namespace std;
const int N=256+5;
bool fail;//bool类型的fail,用于判断,错误赋1,没错赋0
vector<int>ans;
char s[N];
struct Node
{
bool is;//是否被赋值
int value;//结点的值
Node *l,*r;//左右结点
Node():is(false),l(NULL),r(NULL) {
}
};
Node * root;//根结点
Node * newNode()//建新结点
{
return new Node();
}
void remove_tree(Node * root)//清除二叉树
{
if(root==NULL)
return;
remove_tree(root->l);
remove_tree(root->r);
delete root;
}
void insertNode(int t,char * ss)//插入
{
//t表示插入的价值,ss为插入的序列
int n=strlen(ss);
Node *p=root;
for(int i=0; i<n; i++)
{
if(ss[i]=='L')
{
if(p->l==NULL)
p->l=newNode();
p=p->l;
}
else if(ss[i]=='R')
{
if(p->r==NULL)
p->r=newNode();
p=p->r;
}
}//以上步骤负责定位到待插入的结点
if(p->is)//已经赋值过,输入错误
{
fail=true;
}
p->value=t;
p->is=true;
}
//广搜,返回值为是否某一结点未被赋值
bool bfs(vector<int>&ans)//vector作为函数的参数或者返回值时,&不能省
{
queue<Node *>q;//广搜需要的队列
ans.clear();//清除上一次序列
q.push(root);//根结点入队
while(!q.empty())
{
Node *p=q.front();//指针指向第一个元素的位置
q.pop();//剔除第一个元素
if(!p->is)//结点未被赋值
{
return false;
}
ans.push_back(p->value);//将结点的值加到vector的最后面
if(p->l!=NULL)
{
q.push(p->l);//左子结点入队
}
if(p->r!=NULL)
{
q.push(p->r);//右子结点入队
}
}
return true;
}
int main()
{
int c=1;
while(c)
{
remove_tree(root);//清除上一棵二叉树
fail=false;//初始化
root=newNode();
while(1)
{
if(scanf("%s",s)!=1)//如果s被成功读入就返回1,否则返回0
{
c=0;
break;
}
if(!strcmp(s,"()"))//比较字符串s和(),s<()返回-1,s>()返回1,相等返回0
{
break;//如果s==(),停止输入
}
string ss,str(s);//s变成字符串str
ss=str.substr(1);//去掉“(”
int val=atoi(ss.c_str());//字符串转数字
insertNode(val,strchr(s,',')+1);//strchr返回首次出现“,”位置的下一位的指针
//插入结点
}
if(c==0)
continue;
if(!bfs(ans))//如果某一结点没有被赋值,则错误
{
fail=true;
}
if(fail)
{
cout<<"not complete"<<endl;
}
else {
for(int i=0;i<ans.size();i++)
{
if(i!=0)
cout<<" ";
cout<<ans[i];
}
cout<<endl;
}
}
return 0;
}
解题心得:菜鸟忧伤,研究一下午终于仿照人家的代码写出来了,思路上差不多就是老出错,现在还没搞明白啥时候用指针函数和指针参数,暂时先硬记吧,希望做多了能明白套路,先挖个坑。