POJ2255-Tree Recovery

来源:互联网 发布:js金沙.com 11 编辑:程序博客网 时间:2024/05/20 10:23
 Tree Recovery
Time Limit:1000MS     Memory Limit:65536KB  
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

题意:给定一棵二叉树的先序遍历结点序列和中序遍历结点序列,求其后序遍历结点序列。树的结点不超过26。分析:由于遍历都是递归定义的,所以不难得到以下结论:树的任意子树的遍历结点序列一定是该树的遍历结点序列的一个连续子序列。有了这个结论后,我们的任务就是确定子树遍历结点序列的起点和终点,而这个可以根据preorder和inorder得到。例如,preorder的第一个结点是根,设为root,root这个结点会把inorder分为2部分(可能某部分为空),左边的就是左子树的中序遍历结点序列,右边的就是右子树的中序遍历结点序列,这样也就确定了左子树和右子树的结点数目,根据左右子树结点数目,就可得到左右子树的先序遍历结点序列,从而问题就递归了:已知左右子树的先序遍历结点序列和中序遍历结点序列,求后序遍历结点序列,递归求解即可。递归边界是叶子结点。代码如下:

 1 2 3 4 5 6 7 8 9101112131415161718192021222324
#include <cstdio>#include <cstring>#define M 27char pre[M], in[M];int id[M];void postorder(int prest, int pred, int inst, int ined){    int node = id[pre[prest]-'A'];    int l = node-inst;    int r = ined-node;    if( l ) postorder(prest+1,prest+l,inst,node-1);    if( r ) postorder(prest+l+1,pred,node+1,ined);    printf("%c",pre[prest]);}int main(){    while(~scanf("%s%s",pre,in))    {        for(int i = 0; in[i]; i++) id[in[i]-'A'] = i;        int len = strlen(in);        postorder(0, len-1, 0, len-1);        printf("\n");    }}

0 0
原创粉丝点击