在这个问题之前,我们应该知道前序遍历、中序遍历、后序遍历的定义。
前序遍历:访问二叉树的根结点 + 遍历二叉树的左子树 + 遍历二叉树的右子树
中序遍历:遍历二叉树的左子树 + 访问二叉树的根结点 + 遍历二叉树的右子树
后序遍历:遍历二叉树的左子树 + 遍历二叉树的右子树 + 访问二叉树的根结点
根据前序遍历的性质,我们可以知道,前序遍历访问的第一个根结点是这个二叉树T的根结点。
又可以根据中序遍历的性质,得出根节点的左子树和右子树的结点分别是哪些。
举个例子:
前序遍历:GDAFEMHZ
中序遍历:ADEFGHMZ
显然这个二叉树T的根结点为:G
又可以根据中序遍历得出二叉树T的左子树的结点为:A、D、E、F,右子树的结点为:H、M、Z。
根据前序遍历的性质可以知道,挨着G结点的,是二叉树T左子树的根结点。所以二叉树T左子树的根结点为D。
又可以知道,前序遍历先访问到的4个结点一定是二叉树T的左子树,就可以知道二叉树T右子树的根节点为M。
递归下去就可以还原这个二叉树T了,后序遍历便可求出:AEFDHZMG。
同理,已知中序遍历和后序遍历,也可以求出前序遍历。
附上代码:
求后序遍历:
#include <stdio.h>
#include <string.h>
void gao(int n, char *ch1, char *ch2)
{
if(n <= 0)
{
return ;
}
int p = strchr(ch2, ch1[0]) - ch2;
gao(p, ch1+1, ch2); //递归遍历左子树 p为当前节点ch1[0]的左子树的结点个数
gao(n-p-1, ch1+p+1, ch2+p+1); //递归遍历右子树 n-p-1为当前节点ch1[0]的右子树的结点个数
printf("%c", ch1[0]);
}
int main()
{
char ch1[1000], ch2[1000];
int n;
while(scanf("%s %s", ch1, ch2))
{
n = strlen(ch1);
gao(n, ch1, ch2);
puts("");
}
return 0;
}
求前序遍历:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
void gao(int n, char *ch1, char *ch2)
{
if(n <= 0)
{
return ;
}
printf("%c", ch1[0]);
int p = strchr(ch2, ch1[0]) - ch2;
gao(p, ch1+n-p, ch2);
gao(n-p-1, ch1+1, ch2+p+1);
}
int main()
{
char ch1[1000], ch2[1000];
int n;
while(scanf("%s %s", ch1, ch2))
{
minn = 0;
n = strlen(ch1);
for(int i = 0, j = n - 1; i < j; i++, j--)
{
swap(ch1[i],ch1[j]); //翻转ch1串
}
gao(n, ch1, ch2);
puts("");
}
return 0;
}