zoj 1944 Tree Recovery

Tree Recovery
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

Little Valentine liked playing with binary trees very much. Her favorite game was constructing randomly looking binary trees with capital letters in the nodes.  
This is an example of one of her creations:  
                                               D

                                              / \

                                             /   \

                                            B     E

                                           / \     \

                                          /   \     \

                                         A     C     G

                                                    /

                                                   /

                                                  F


To record her trees for future generations, she wrote down two strings for each tree: a preorder traversal (root, left subtree, right subtree) and an inorder traversal (left subtree, root, right subtree). For the tree drawn above the preorder traversal is DBACEGF and the inorder traversal is ABCDEFG.  
She thought that such a pair of strings would give enough information to reconstruct the tree later (but she never tried it).  

Now, years later, looking again at the strings, she realized that reconstructing the trees was indeed possible, but only because she never had used the same letter twice in the same tree.  
However, doing the reconstruction by hand, soon turned out to be tedious.  
So now she asks you to write a program that does the job for her!  

Input

The input will contain one or more test cases.  
Each test case consists of one line containing two strings preord and inord, representing the preorder traversal and inorder traversal of a binary tree. Both strings consist of unique capital letters. (Thus they are not longer than 26 characters.)  
Input is terminated by end of file.  

Output

For each test case, recover Valentine's binary tree and print one line containing the tree's postorder traversal (left subtree, right subtree, root).

Sample Input

DBACEGF ABCDEFG
BCAD CBAD

Sample Output

ACBFGED
CDAB


    题目大意: 根据前序遍历和中序遍历找到后序遍历。

思路:类似于快速排序的思想。找到”中枢节点“之后,逐渐的缩减递归问题规模。一直到找到叶子节点。

#include<stdio.h>
#include<string.h>
char s1[30],s2[30];
int i;
void dfs(int left,int right)
{
	int mid;
	if(left>right) //递归终止的条件。
		return ;
	if(left==right) //遍历到叶子节点输出。
	{
		++i;
		printf("%c",s2[left]);//输出中序串中叶子节点。
		return;
	}
	for(mid=left;mid<=right;++mid)
	{
		if(s1[i]==s2[mid])//在中序中找到子树和树的根节点。	
		    break;
	}
	++i; 		//i++中序与前序的下一个字母进行比较。
	dfs(left,mid-1); //遍历左子树的左子树一直到最后一个左子树的叶子节点。
	dfs(mid+1,right);//遍历右子树的右子树一直到最后一个右子树的叶子节点。
	printf("%c",s2[mid]);//输出子树和树的根节点。
}
int main()
{
	int root,l;
	while(scanf("%s%s",s1,s2)!=EOF)
	{
		l=strlen(s1);
		i=0;
		dfs(0,l-1);
		printf("\n");
	}
	return 0;
}



 

 运行思路。

中序串               A B C D E F G

中序串和后序串的关系,中序串一般有左右孩子的话,都是左右孩子夹着根节点,而后序遍历从左孩子,到右孩子再根节点。

正好可以递归调用下面这三个方法。

dfs(left,mid-1); //遍历左子树的左子树一直到最后一个左子树的叶子节点。

dfs(mid+1,right);//遍历左子树的右子树一直到最后一个右子树的叶子节点。

printf("%c",s2[mid]);//输出子树和树的根节点。

 

1,首先根据前序串找到树的根节点(16-19行for循环) D 。

2,递归调用dfs(left,mid-1); 找到左子树的根节点 B。

3,再递归调用dfs(left,mid-1); 找到左子树的左孩子节点A 。(根据中序串AB,若是右孩子应该是BA。B是左子树的根节点)。

 4,这时候left ==right 输出A

5,调用dfs(mid+1,right); ,把左子树根节点B的右节点打印出来 C。

6,输出mid(mid就相当根节点的位置。),返回上一级。。。再继续

 

这里一个重要的输出,条件是left==right,为什么这里要输出呢?

因为mid就是中序串中根节点的位置。mid前面为左孩子,右边为右孩子。。

而递归左子树方法 dfs(left,mid-1);

和递归右子树的方法 dfs(mid+1,right);

里面的实参正好使left==right。

而后序遍历从左孩子,到右孩子再根节点。完美的递归。。

orz大神。。。

 

 

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值