Time Limit: 1 Sec Memory Limit: 32 MB
Submit: 3 Solved: 3
[Submit][Status][Web Board]
Description
二叉树的前序、中序、后序遍历的定义:
前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树;
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树;
后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。
Input
两个字符串,其长度n均小于等于26。
第一行为前序遍历,第二行为中序遍历。
二叉树中的结点名称以大写字母表示:A,B,C....最多26个结点。
Output
输入样例可能有多组,对于每组测试样例,
输出一行,为后序遍历的字符串。
Sample Input
ABC
CBA
ABCDEFG
DCBAEFG
Sample Output
CBA
DCBGFEA
HINT
Source
【分析】
一个前序遍历序列和一个中序遍历序列可以确定唯一二叉树。
根据前序遍历的特点, 知前序序列的首个元素为二叉树的根, 然后在中序序列中查找此根,根据中序遍历特点, 知在查找到的根 前边的序列为根的左子树的中序遍历序列, 后边的序列为根的右子树的中序遍历序列。 设在中序遍历序列根前边有left个元素. 则在前序序列中, 紧跟着根的left个元素序列(即PreSequence[1...left]) 为根的左子树的前序遍历序列, 在后边的为根的右子树的前序遍历序列.而构造左子树问题其实跟构造整个二叉树问题一样,只是此时前序序列为PreSequence[1...left]), 中序序列为InSequence[0...left-1], 分别为原序列的子串, 构造右子树同样, 显然可以用递归方法解决。每次将根结点的数据赋值,然后不断的递归调用创建左右子树,直到不存在左右子树时函数返回。
下图来自博客:https://blog.csdn.net/qq_33951180/article/details/72790549#commentBox
【代码】
#include<bits/stdc++.h>
using namespace std;
const int maxn=30;
char order[maxn],in[maxn];
int cur;
typedef struct treenode{
struct treenode * left;
struct treenode * right;
char val;
}*tree,node;
int findRoot(char x,int n)
{
for(int i=0;i<n;i++)
if(in[i]==x)return i;
return -1;
}
void build(tree &T,int left,int right,int n)//建树
{
if(right<left||cur>=n)return;
char root=order[cur];//前序
cur++;
//int len=strlen(order);
int index=findRoot(root,n);//cout<<"index="<<index<<endl;
T=new node();
T->val=root;
if(right==left)
{
T->left=NULL;
T->right=NULL;
}
else{
build(T->left,left,index-1,n);
build(T->right,index+1,right,n);
}
}
void post(tree &T)
{
// if(T==NULL)return;
// queue<tree>q;
// q.push(T);
// while(!q.empty())
// {
// tree c=q.front();cout<<"kjh:"<<c->val<<endl;
// q.pop();
// if(c->left!=NULL)q.push(c->left);
// if(c->right!=NULL)q.push(c->right);
// printf("%c",c->val);
// }
if(T)
{
post(T->left);
post(T->right);
cout<<T->val;
}
}
int main()
{
tree T;
while(~scanf("%s",order))
{
scanf("%s",in);
cur=0;
int n=strlen(order);
build(T,0,n-1,n);
post(T);
cout<<endl;
}
return 0;
}