D
/ \
/ \
B E
/ \ \
/ \ \
A C G
/
/
F
Input
Output
Sample Input
DBACEGF ABCDEFG
BCAD CBAD
Sample Output
ACBFGED
CDAB
有两种思路,一种是先构建树;再后序访问输出,
前序的第一个节点必是这棵树的根节点,
而根节点在中序的位置是它的左子树和右子树的边界,
由此我们也就知道了该根节点的左子树和右子树的前序和中序;
问题则变为构建根的左子树和右子树,并把这两棵树与根节点连起来,递归调用,最终整棵树构建起来;
另一种思路是利用递归的思想,因为相对于根节点的左子树,和右子树都是一棵独立的树;
按照后序的访问顺序:左子树,右子树,根;
最终的结果也即是 左子树的后序 + 右子树的后序 + 根节点;
所以如果我们得到了一个求后序的函数;那么先求左子树的后序,再求右子树的后序,再输出根节点,即是答案;
#include < stdio.h >
#include < string .h >
#include < stdlib.h >
struct node{
char value;
struct node * left, * right;
};
void make_tree( char * pre, char * mid, struct node * root)
{
int i,len;
int flag = 0 ,flag1 = 0 ;
struct node * ptr1, * ptr2;
char ppre[ 28 ],mmid[ 28 ];
for (i = 0 ;mid[i] != pre[ 0 ];i ++ ); // 找到根节点在中序中的位置
if (i != 0 ) // 判断左子树是否存在
flag = 1 ;
if (i != ( int )strlen(mid) - 1 ) // 判断右子树是否存在
flag1 = 1 ;
if (flag) // 构建该根的左子树
{
ptr1 = ( struct node * )malloc( sizeof ( struct node));
ptr1 -> value = pre[ 1 ];
root -> left = ptr1; // 该根与左子树建立联系
if (flag1 == 0 )
root -> right = NULL;
strncpy(ppre,pre + 1 ,i); // 左子树的前序
strncpy(mmid,mid,i); // 左子树的中序
ppre[i] = mmid[i] = 0 ;
make_tree(ppre,mmid,ptr1); // 已知左子树的前序和中序,构建左子树
// free(ptr1);
}
if (flag1) // 构建该根的右子树
{
ptr2 = ( struct node * )malloc( sizeof ( struct node));
ptr2 -> value = pre[i + 1 ];
root -> right = ptr2; // 该根与右子树建立联系
if (flag == 0 )
root -> left = NULL;
len = strlen(pre) - i - 1 ;
strncpy(ppre,pre + i + 1 ,len); // 得到右子树的前序
strncpy(mmid,mid + i + 1 ,len); // 得到右子树的中序
ppre[len] = mmid[len] = 0 ;
make_tree(ppre,mmid,ptr2); // 根据它的前序和中序,构建右子树
// free(ptr2);
}
if (strlen(pre) == 1 )
root -> left = root -> right = NULL;
}
void visit( struct node * p) // 后序遍历树
{
if (p == NULL)
return ;
visit(p -> left);
visit(p -> right);
printf( " %c " ,p -> value);
}
int main()
{
char pre[ 28 ],mid[ 28 ];
while (scanf( " %s%s " ,pre,mid) != EOF)
{
struct node * root;
root = ( struct node * )malloc( sizeof ( struct node));
root -> value = pre[ 0 ];
make_tree(pre,mid,root);
visit(root);
putchar( ' \n ' );
}
return 0 ;
}
第二种思路(递归方法)的代码
#include < stdio.h >
#include < string .h >
#define M 30
char stack[M];
int top;
void Create( char * pre, char * mid)
{
char ps1[M],ps2[M], * qs1, * qs2;
int index;
if (strlen(pre))
{
stack[top ++ ] = pre[ 0 ];
index = strchr(mid,pre[ 0 ]) - mid;
qs1 = mid;qs2 = mid + index + 1 ;
mid[index] = 0 ;
strncpy(ps1,pre + 1 ,index);
ps1[index] = 0 ;
strcpy(ps2,pre + index + 1 );
Create(ps2,qs2);
Create(ps1,qs1);
}
return ;
}
int main()
{
char pre[M],mid[M];
while (scanf( " %s%s " ,pre,mid) !=- 1 )
{
top = 0 ;
Create(pre,mid);
while (top > 0 )
printf( " %c " ,stack[ -- top]);
puts( "" );
}
return 0 ;
}