Tree Recovery
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 21167 | Accepted: 12818 |
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:
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!
This is an example of one of her creations:
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!
D
/ \
/ \
B E
/ \ \
/ \ \
A C G
/
/
F
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.
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
题目大意:给你二叉树的先序和中序遍历,求后序遍历序列。
解题思路:根据前序遍历和中续遍历恢复这颗树,再进行后序遍历得到结果。
还原方法:根据前序遍历可知,第一个节点一定是根节点,然后从中序遍历中找到这个节点的位置x,在中序遍历中x这个位置处分开分成左右子树,循环递归下去恢复这颗树。
AC代码:
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
using namespace std;
const int maxn=1e5+10;
string pre,in; //先序遍历和中序遍历的字符串
int tree[maxn]; //这里用字符的ASCII码存所以用int,
//根据题目要求如果是一颗斜树的话是不够的数组大小,但是样列一般所以1e5能过
//恢复树
void Restor_tree(int node,int prel,int prer,int inl,int inr){ //树当前节点位置node和前序中序的区间
if(prel>prer){ //当区间为负则退出
return;
}
tree[node]=(int)(pre[prel]-'A'); //当前节点一定的值为前序的第一个节点
int k=0;
for(k=inl;k<=inr;k++){ //中序遍历中寻找根节点位置
if(in[k]==pre[prel]) break;
}
int lson_len=k-inl; //左子树的长度
Restor_tree(node*2 , prel+1,prel+lson_len , inl,k-1); //左子树继续恢复
Restor_tree(node*2+1 , prel+lson_len+1,prer , k+1,inr); //右子树继续恢复
}
//后序遍历
void Post_order(int node){
if(tree[node]==-1) return; //该节点没有值
Post_order(node*2); //遍历左子树
Post_order(node*2+1); //遍历右子树
cout << (char)(tree[node]+'A'); //输出当前节点
}
int main(){
while(cin >> pre >> in){
memset(tree,-1,sizeof(tree));
int pre_len=pre.size()-1; //初始长度
int in_len=in.size()-1;
Restor_tree(1,0,pre_len,0,in_len); //根节点从1开始
Post_order(1);
cout << endl;
}
return 0;
}