题目描述:
输入一颗二叉树,你的任务是按从上到下,从左到右的顺序输出各个节点的值。每个节点都按照从根节点到它的移动序列给出(L表示左,R表示右)。在输入中,每个节点的左括号和有括号之间没有空格,相邻节点之间用一个空格隔开。每棵树的输入用一对空括号()结束(这对括号本身不代表一个节点)。注意,如果从根到某个叶节点的路径上有的节点没有在输入中给出,或者给出了超过一次,应当输出-1.节点个数不超过256.
直接上代码,代码有详细注释。代码末尾附上测试用例
#include <iostream>
#include <string>
#define maxn 256 //因为最多只有256个节点
using namespace std;
struct node //构造节点结构体
{
int have_value; //记录节点是否已经被赋过值,若已被赋过值则为1,否则为0
int value; //记录节点的值
node *left,*right;//left,right分别指向左右儿子
};
int iterate=0; // 记录输入数据中是否有重复赋值的点,若有则值为1
int nodenum=0; //记录节点的数量
int ans[256]={0}; //记录每个节点的value,初始化为0
node *root=NULL; //定义一个全局的根节点
node* newnode() //节点创建函数
{
node *p=new node;
if(p!=NULL) //如果创建成功,则继续下列步骤
{
p->have_value=0; //刚创建的节点把have-value赋值为0,因为value还未赋值
p->left=p->right=NULL;
}
return p;
}
void addnode(int v,string str)//节点添加函数,即把节点添加到二叉树中
{
node *p=root;
str=str.erase(0,1); //第一个字符是逗号,所以删去
for(int i=0;i<str.length();i++)//一路循环遍历下去,一直到最终要添加的节点,期间可能会创建许多其他后续要添加的节点
{ //这正是我们所需要的
if(str[i]=='L')
{
if(p->left==NULL)p->left=newnode();
p=p->left;
}
if(str[i]=='R')
{
if(p->right==NULL)p->right=newnode();
p=p->right;
}
}
if(p->have_value==1)iterate=1; //如果要添加的节点已经被添加过,即在输入序列中重复出现,则把iterate赋值为1
else
{
p->value=v;
p->have_value=1;
}
}
int bfsoutput()//利用宽度搜索遍历二叉树,把各个节点的值记录到ans数组中
{
int front=0,rear=1;
node *p[maxn];
p[0]=root;
while(front<rear)
{
node *q=p[front++];
if(q->have_value==0)return 0;//如果其中某个节点仍未被赋值,即在输入序列中为出现过则返回,输出-1
ans[nodenum++]=q->value;
if(q->left!=NULL)p[rear++]=q->left;
if(q->right!=NULL)p[rear++]=q->right;
}
return 1;
}
void deletelist(node *p)//链表删除函数,程序末尾一定要调用此函数,否则会造成内存泄漏
{
if(p==NULL)return;
else
{
deletelist(p->left);//利用递归删除节点
deletelist(p->right);
delete p;
}
}
int main()
{
root=newnode();//优先创建根节点
string str;
while(cin>>str)
{
if(str=="()")break;
int v=0;string dir;
for(int i=0;i<str.length();i++)
{
if(str[i]>='0'&&str[i]<='9')v=v*10+(str[i]-48);
else if(str[i]=='L'||str[i]=='R'||str[i]==',')dir=dir+str[i];
}
if(dir.length()==1)//如果dir长度为一,即只有一个逗号则这个节点为根节点
{
root->value=v;root->have_value=1;
}
else addnode(v,dir);
}
if(iterate==1)cout<<-1;//如果输入虚了出现重复出现的情况则输出-1
else
{
int pan=bfsoutput();
if(!pan)cout<<-1;// 如果输入序列存在某个节点未出现的情况则输出-1
else
{
for(int i=0;i<nodenum;i++)
cout<<ans[i]<<' ';
cout<<'\n';
}
}
deletelist(root);
}
/*
(11,LL) (7,LLL) (8,R) (5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()
(3,L) (4,R) ()
*/
1243

被折叠的 条评论
为什么被折叠?



