C++实现—层次遍历

题目描述:

输入一颗二叉树,你的任务是按从上到下,从左到右的顺序输出各个节点的值。每个节点都按照从根节点到它的移动序列给出(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) () 
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值