题意:已知一个二叉树的先序和中序,求其后序遍历的结果
分析:由先序(根左右)可确定根,再由中序和根,可确定其左子树和右子树,
对于左右子树又可以确定根,及其左右子树。。。递归思想
代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct stu
{
char c;
struct stu *l,*r;
}Tree;
void creat(Tree **T,char *z,int m1,int n1,char *x,int m2,int n2) //m1,n1,m2,n2分别为中序和先序子树的其实位置
{
int i;
*T=NULL;
if(m1==n1){
*T=(Tree *)malloc(sizeof(Tree));
(*T)->c=z[m1];
(*T)->l=(*T)->r=NULL;
}
else{
for(i=m1;i<=n1;i++) //子树中,先序的第一个结点为根,在中序中找到根,根左边为左子树,右边为右子树
if(z[i]==x[m2])
break;
*T=(Tree *)malloc(sizeof(Tree));
(*T)->c=x[m2];
if(i-1>=m1&&i+1<=n1){ //当左右孩子都存在时
creat(&(*T)->l,z,m1,i-1,x,m2+1,m2+i-m1); //先构建左子树
creat(&(*T)->r,z,i+1,n1,x,m2+i-m1+1,n2); //再构建右子树
}
else if(i-1<m1&&i+1<=n1){ //只有右孩子时
creat(&(*T)->r,z,i+1,n1,x,m2+i-m1+1,n2);
(*T)->l=NULL;
}
else if(i-1>=m1&&i+1>n1){ //只有左孩子时
creat(&(*T)->l,z,m1,i-1,x,m2+1,m2+i-m1);
(*T)->r=NULL;
}
}
}
void printh(Tree *T)
{
if(T!=NULL){
printh(T->l);
printh(T->r);
printf("%c",T->c);
}
}
int main()
{
int n1,n2;
char x[30],z[30];
Tree *T=NULL;
while(scanf("%s%s",x,z)!=EOF){
n1=strlen(z);
n2=strlen(x);
creat(&T,z,0,n1-1,x,0,n2-1);
printh(T);
printf("\n");
}
return 0;
}