首页 > 其他 > 详细

NYOJ--重建二叉树

时间:2014-04-16 15:49:59      阅读:473      评论:0      收藏:0      [点我收藏+]

重建二叉树

时间限制:1000 ms  |  内存限制:65535 KB
难度:3
描述
题目很简单,给你一棵二叉树的后序和中序序列,求出它的前序序列(So easy!)。
输入
输入有多组数据(少于100组),以文件结尾结束。
每组数据仅一行,包括两个字符串,中间用空格隔开,分别表示二叉树的后序和中序序列(字符串长度小于26,输入数据保证合法)。
输出
每组输出数据单独占一行,输出对应得先序序列。
样例输入
ACBFGED ABCDEFG
CDAB CBAD
样例输出
DBACEGF
BCAD
来源

原创

解析:这是一道数据结构中很水的题,可惜自己因为文件结束符EOF这个TLE了很多次,唉……粗心哈!先简单说一下二叉树的遍历

先序遍历二叉树:先序遍历根节点,先序遍历左子树,先序遍历右子树,也就是NLR

中序遍历二叉树:中序遍历左子树,中序遍历根节点,中序遍历右子树,也就是LNR

后序遍历二叉树:后序遍历左子树,后序遍历右子树,后序遍历根节点,也就是LRN

要想由这三种遍历二叉树的序列重建唯一的二叉树则至少得有两种遍历序列,且这两种中一定要有中序序列,也就是先序+中序-->二叉树  或者  后序+中序-->二叉树,而先序+中序得不到唯一的二叉树。

下面看一下这三种遍历的特点,首先先序序列总是先遍历根节点,所以它的序列的第一个必然是整个二叉树的根节点,相反,后序遍历的序列最后一个必然是二叉树的根节点,通过缺点了二叉树的根节点,在中序序列中找到这个根节点,因为中序序列是先遍历左字数再遍历根节点,然后是右子树,所以在中序序列中的根节点左边的节点全都是左子树的,右边的序列都应该是右子树的,接着递归的应用就可以得到整个二叉树了(不知道说清楚的没)

后序序列:ACBFGED

中序序列:ABCDEFG

首先确定D是整个二叉树的根节点,然后在中序序列中找到D则其左边的ABC就是D的左子树,EFG就是 D的右子树。

提取出左字数的后序和中序序列

后序序列:ACB

中序序列: ABC

后序序列的最后一个字符是B则B是当前子树的根节点,然后在中序序列中找到B则左边的A是B的左子树,C是B的右子树。

以此递推就可以得到整个二叉树的结构了,如下图所示

bubuko.com,布布扣

同样知道先序序列和中序序列后也可以构建出唯一的二叉树,掌握的思想,下面就是用代码实现的事情了。

代码本着重建二叉树的原则,并没考虑太多OJ时间和空间的限制,但AC还是可以的,在代码中我右加上了先序+中序-->二叉树的函数

当然在实际的OJ上做类似的题时不用那么麻烦根根节点分配空间,直接输出就好了,我只不过是想将二叉树建立起来,看起来比较直观而已

#include <stdio.h>
#include <malloc.h>
#include <string.h>
//二叉链表
typedef struct node{
	char data;//节点数据元素
	struct node *lchild;//指向左孩子
	struct node *rchild;//指向右孩子
}BiNode,*BTree;
//利用后序和中序建立二叉树
void GetPreOrder(char *last,char *mid,BTree &T,int len)
{
	if(len==0)
	{
		T = NULL;
		return;
	}
	//取出后序序列中的最后一个节点
	char ch=last[len-1];
	int index=0;
	//在中序序列中进行查找根节点,并用index记录其在序列中的索引
	while(mid[index]!=ch)
	{
		index++;
	}
	//给根节点分配空间
	T=(BTree)malloc(sizeof(BiNode));
	T->data=mid[index];
	//建立左子树
	GetPreOrder(last,mid,T->lchild,index);
	//建立右子树
	GetPreOrder(last+index,mid+index+1,T->rchild,len-index-1);
}
void GetPostOrder(char *prim,char *mid,BTree &T,int len)
{
	if(len==0)
	{
		T=NULL;
		return;
	}
	//提出先序序列中的第一个节点
	char ch=prim[0];
	int index=0;
	//在中序序列中查找当前根节点,并用index记录其在序列中的位置
	while(mid[index]!=ch)
	{
		index++;
	}
	//给根节点分配空间
	T=(BTree)malloc(sizeof(BiNode));
	T->data=mid[index];
	//建立左子树
	GetPostOrder(prim+1,mid,T->lchild,index);
	//建立右子树
	GetPostOrder(prim+index+1,mid+index+1,T->rchild,len-index-1);
}
//先序输出二叉树
void PreOrder(BTree T)
{
	if(T!=NULL)
	{
		printf("%c",T->data);
		PreOrder(T->lchild);
		PreOrder(T->rchild);
	}
}
//后序输出二叉树
void PostOrder(BTree T)
{
	if(T!=NULL)
	{
		PostOrder(T->lchild);
		PostOrder(T->rchild);
		printf("%c",T->data);
	}
}
int main()
{
	char first[26],mid[26],last[26];
	while(scanf("%s%s",last,mid)!=EOF)
	{
		BTree T=NULL;
		GetPreOrder(last,mid,T,strlen(last));
		PreOrder(T);
// 		GetPostOrder(last,mid,T,strlen(last));
// 		PostOrder(T);
		printf("\n");
	}
	return 0;
}

NYOJ--重建二叉树,布布扣,bubuko.com

NYOJ--重建二叉树

原文:http://blog.csdn.net/computer_liuyun/article/details/23738567

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!