UVA 536 Tree Recovery(由前序中序求后序,经典)

Tree Recovery

Time Limit: 3000 MS



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 Specification

The input file 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 Specification

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<iostream>
#include<string>
#include<cstdio>
using namespace std;

const int maxN = 30;
struct Node{
    char ch;
    int l,r;
    Node(int l0=0,int r0=0){l=l0,r=r0;}
}tree[maxN];
string pre,in,post;
int index;

void build(string preOrder,string inOrder){
    int temp=index;
    tree[temp]=Node(-1,-1);
    tree[temp].ch=preOrder[0];
    //if(preOrder.length()==1) return ;

    for(int i=0;i<preOrder.length();i++){
        if(inOrder[i]==preOrder[0]){
            if(i>0){//如果有lson
                string lpre=preOrder.substr(1,i);
                string lin=inOrder.substr(0,i);
                tree[temp].l=++index;
                build(lpre,lin);
            }
            if(i<preOrder.length()-1){//如果有rson
                string rpre=preOrder.substr(i+1);
                string rin=inOrder.substr(i+1);
                tree[temp].r=++index;
                build(rpre,rin);
            }
        }
    }
}

void solve(){
    post.clear();
    index=0;
    build(pre,in);
}

void postMake(int cnt){
    if(tree[cnt].l!=-1) postMake(tree[cnt].l);
    if(tree[cnt].r!=-1) postMake(tree[cnt].r);
    post.push_back(tree[cnt].ch);
}

void output(){
    cout<<post<<endl;
}

int main(){
    while(cin >> pre >> in){
        solve();
        postMake(0);
        output();
    }
    return 0;
}

代码二:(老师写的赞赞的代码,耶)

/*
UVa536 Tree Recovery
Coded by Guojin Zhu
Run Time 0.008s
AC on November 2,2012
*/
#include<iostream>
#include<string>
using namespace std;
///////////////////
class TreeRecovery{
private:
    string preord;
    string inord;
    string postorder;
    void reconstruct(string p, string i);
public:
    void initial(string p, string i){
        preord = p;
        inord = i;
        postorder.clear();
    }
    void computing(){reconstruct(preord, inord);}
    void outResult(){cout << postorder << endl;}
};
void TreeRecovery::reconstruct(string preord, string inord){
    int sz = preord.size();
    if(sz > 0){
        int p = int(inord.find(preord[0]));
        reconstruct(preord.substr(1, p), inord.substr(0, p)); //left subtree
        reconstruct(preord.substr(p+1, sz-p-1), inord.substr(p+1, sz-p-1)); //right subtree
        postorder.push_back(preord[0]); //root
    }
}
/////////////////////
int main(){
    TreeRecovery tr;
    string p, i;
    while(cin >> p >> i){
        tr.initial(p, i);
        tr.computing();
        tr.outResult();
    }
    return 0;
}
/*
INPUT
DBACEGF ABCDEFG
BCAD CBAD
AB BA
--------------
OUTPUT
ACBFGED
CDAB
BA
*/
时间: 2024-08-10 19:19:15

UVA 536 Tree Recovery(由前序中序求后序,经典)的相关文章

Uva 536 Tree Recovery

1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 string pr,in; 6 string postorder; 7 void process(string preord,string inord); 8 int main() 9 { 10 //freopen("D:\\acm.txt","r",stdin); 11 while(cin>>

PAT A1086 Tree Traversals Again [二叉树前序中序求后序]

题目描述 链接 用栈的形式给出一棵二叉树的建立的顺序,求这棵二叉树的后序遍历 分析 性质:树的先序等于入栈次序,树的中序遍历等于出栈次序 先序:先访问根再入栈,所以入栈次序就是先序遍历次序 中序:先递归访问左子树,回溯时访问根,回溯时即出栈时,所以出栈次序就是中序遍历 所以问题转换为已知先序中序,求后序 已知先序中序求后序的方法 \(root\) 保存先序中根的位置,\(st\),\(ed\) 为中序子树的起始结束位置 遍历中序,找到中序根的位置\(i\),从而分成左右子树 左子树在先序中根的位

HDU 1710 二叉树遍历,输入前、中序求后序

1.HDU  1710  Binary Tree Traversals 2.链接:http://acm.hust.edu.cn/vjudge/problem/33792 3.总结:记录下根结点,再拆分左右子树,一直搜下去.感觉像dfs. 题意:二叉树,输入前.中序求后序. (1)建立出一颗二叉树,更直观.但那些指针用法并不是很懂. #include<iostream> #include<cstdio> #include<cstdlib> using namespace

关于二叉树的问题1-已知前序,中序求后序遍历

对于一棵二叉树而言,可以由其前序和中序或者中序和后序的遍历序列,确定一棵二叉树. 那么对于已知前序和中序序列,求后序序列也就是先还原二叉树,然后对其进行后序遍历即可. 二叉树结点的结构定义如下: struct TreeNode { char value; TreeNode *leftChild; TreeNode *rightChild; }; 实现代码如下: #include <stdio.h> #include <string.h> #include <stdlib.h&

NOJ 2015年陕西省程序设计竞赛网络预赛(正式赛)(小女警的异世界之战-前序中序求后序)

A - 小女警的异世界之战 Time Limit: 1000 ms        Memory Limit: 65536 KB Submit Description 这一天,小女警花花,泡泡和毛毛来到终极Boss"Him"所在的异世界并准备与其决一死战,却被困在了他的城堡里.她们发现异世界是一个巨大的城堡.城堡由一个个大小不同的房间组成,房间有着以下的规则: 每个房间有且仅有一扇黄门,此外至多有一扇红门和一扇绿门:黄色代表通向更大的房间,绿色和红色代表通向更小的房间.很显然,如果你打开

UVa 二叉树重建(先序+中序求后序)

题意是给出先序和中序,求出后序. 先序遍历先访问根结点,通过根结点可以在中序中把序列分为左子树部分和右子树部分,我建了一个栈,因为后序遍历最后访问根结点,所以把每次访问的根结点放入栈中.因为后序遍历先是左子树然后是右子树,所以在递归的时候就先递归右子树,然后继续递归左子树. 写完程序后有个错误,找了很久才发现,就是我原本在计算左子树个数的时候,是这样计算的,pre2=mid-pre,但是当pre>mid时,就不对了.而正确计算左子树的方法应该是下面这样的. 1 #include<iostrea

已知前序中序求后序-二叉树

writer:pprp 思路很容易理解,但是实现还是有一点难度,容易错 参考书目:<算法竞赛宝典> 代码如下: //已知前序中序,求后序 #include <iostream> using namespace std; //a是前序,b是中序 void hwg(string a,string b) { int ll,lr; for(unsigned int i = 0; i < b.length(); i++) { if(a[0] == b[i]) //找到根节点 { ll

UVa 536 Tree Recovery(先序,中序求后序)

题意  给你二叉树的先序序列和中序序列  求它的后序序列 先序序列的第一个一定是根  中序序列根左边的都属于根的左子树  右边的都属于右子树  递归建树就行了 #include <bits/stdc++.h> using namespace std; typedef struct TNode { char data; TNode *lc, *rc; } node, *BTree; void build(BTree &t, string pre, string in) { t = new

UVa 536 Tree Recovery | GOJ 1077 Post-order (习题 6-3)

传送门1: https://uva.onlinejudge.org/external/5/536.pdf 传送门2: http://acm.gdufe.edu.cn/Problem/read/id/1077 题意一样   输入不一样 HINT: 1. Preorder : (root, left subtree, right subtree); Inorder : (left subtree, root, right subtree); Postorder: (left subtree, rig