Tree Recovery(二叉搜索树 知前中求后)

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

题意:已知一颗二叉搜索树的前序,中序遍历的结果。确定这颗二叉树,并输出后续遍历的结果。

思路:首先我们要知道三种遍历方式:

       前序遍历:先根再左再右。

       中序遍历:先左再根再右。

       后序遍历:先左再右再根。

我们可以根据前序遍历和后续遍历的特点来进行分析,由于前序遍历的第一个值肯定是树的根,而在中序遍历中,树根的左边是左子树,右边是右子树,由此就把树分成的两边。当然在前序中找到的每个节点,在中序中总存在 在相应的区间下(子树的节点数)把树分成两边的结论。

总的来说:先序遍历的每个节点,都是当前子树的根节点。同时,以对应的节点为边界,就会把中序遍历分为左子树和右子树。两次递归,即可建树。

1.先以当前先序的第一个为 根

2.在中序中(首a,尾b)找到这个根c。(a,c)左子树的范围,(c,b)右子树的范围。 (注:a,b,c是中序序列的下标)

3.分区间递归求当前子树的左子树,以及右子树

代码如下:

/*
根据先序遍历和中续遍历的特点来说,
在先序中取一节点,这一点便是当前字树的根节点
同时可以根据这个字树的大小,可以把中序中对应的区间分成左子树和右子树
*/
#include<stdio.h>
#include<string.h>
#include<malloc.h>
struct node  //链表
{
    char val;
    node *lch,*rch;
};
node *insert(char *s,char *t,int l)
{
    if(l<=0) //区间为空
        return NULL;
    node *root=(node*)malloc(sizeof(node));//定义一个动态空间
    root->val=*s;//当前子树的根
    char *p;
    for(p=t;p!=NULL;p++)
        if(*p==*s)       //在中序遍历结果中找到 当前根,此时在中序序列中此根左边是左子树,右边是右子树
            break;
    int k=p-t;   //区间的大小
    root->lch=insert(s+1,t,k);//找当前子树的左子树,
    root->rch=insert(s+k+1,p+1,l-k-1);//找当前子树的右子树
    return root;
}
void print(node *root)//输出后序遍历的结果
{
    if(root==NULL)
        return;
    print(root->lch);
    print(root->rch);
    printf("%c",root->val);
}
int main()
{
    char s[30],t[30];
    while(~scanf("%s %s",s,t))
    {
        int l=strlen(s);
        node *root=(node*)malloc(sizeof(node));//开辟动态空间
        root = insert(s,t,l);//建树
        print(root);
        printf("\n");
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值