层次遍历

输入一颗二叉树,你的任务是按从上到下,从左到右的顺序输出各个节点的值。每个节点都按照从根节点到它的移动序列给出(L表示左,R表示右)。在输入中,每个节点的左括号之间没有空格,相邻节点之间用一个空格隔开。每棵树的输入用一对空括号()结束(这对括号本身不代表一个结点),如图所示。
在这里插入图片描述
注意,如果从根到某个叶节点的路径上有的结点没有再输入中给出,或者给出了超过一次,应当输出-1.结点个数不超过256.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*
测试数据:
(11,LL) (7,LLL) (8,R) (5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()
样例输出:
5 4 8 11 13 4 7 2 1 
*/
const int MAXN = 2000;
char s[MAXN + 10];//保存读入结点 
int failed;
int n;//节点数
int ans[MAXN];//输出序列  

//结点类型
typedef struct Tnode
{
	int have_value;//是否被赋过值 
	int v;//结点值 
	struct Tnode *left, *right;//创建左右儿子 
}Node; 
Node *root;

//申请新结点 
Node *newnode()
{
	Node *u = (Node*)malloc(sizeof(Node));//申请动态内存 
	if (u != NULL)//若申请成功 
	{
		u->have_value = 0;//显式初始化为0,因为malloc申请内存时并不把它清零 
		u->left = u->right = NULL;//初始时没有左右儿子 
	}
	return u;
}

//按照移动序列行走, 目标不存在时调用newnode来创建新结点 
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;//往右走
		}
		else//忽略多余的右括号 
		{
			;
		} 
	}
	if (u->have_value)//已经赋过值,表明输入有误 
	{
		failed = 1;
	}
	u->v = v;
	u->have_value = 1;//结点赋值后做标记 
} 

//释放二叉树存储空间
void remove_tree(Node *u)
{
	if (u == NULL)
	{
		return;
	} 
	remove_tree(u->left);//递归释放左子树空间 
	remove_tree(u->right);//递归释放右子树空间 
	free(u);//释放u结点本身的内存 
} 

//层次遍历二叉树
int bfs()
{
	int front = 0; 
	int rear = 1;
	Node *q[MAXN];
	q[0] = root;//初始时只有一个根结点 
	while (front < rear)
	{
		Node *u = q[front++];
		if (!u->have_value)//有结点没有赋过值,表明输入有误 
		{
			return 0;
		}
		ans[n++] = u->v;//增加到输出序列尾部 
		if (u->left != NULL)//把左儿子(如果有)放进序列 
		{
			q[rear++] = u->left;
		}
		if (u->right != NULL)//把右儿子(如果有)放进序列 
		{
			q[rear++] = u->right;
		}
	} 
	return 1;//输入正确 
}
 
//输入二叉树 
void read_input()
{
	failed = 0;
	remove_tree(root);
	root = newnode();//创建根结点 
	while (1)
	{
		scanf("%s", s); 
		if (!strcmp(s, "()"))//读到结束标志,退出循环 
		{
			break;
		}
		int v;
		sscanf(&s[1], "%d", &v);//读入结点值 
		addnode(v, strchr(s, ',') + 1);//查找逗号, 然后插入结点 
	}
}

int main()
{
	read_input();
	bfs();
	if (failed == 1)
	{
		printf("-1");
	}
	for (int i = 0; i < n; i++)
	{
		printf("%d ", ans[i]);
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值