题目大意: 根据前序遍历和中序遍历找到后序遍历。
思路:类似于快速排序的思想。找到”中枢节点“之后,逐渐的缩减递归问题规模。一直到找到叶子节点。
#include<stdio.h>
#include<string.h>
char s1[30],s2[30];
int i;
void dfs(int left,int right)
{
int mid;
if(left>right) //递归终止的条件。
return ;
if(left==right) //遍历到叶子节点输出。
{
++i;
printf("%c",s2[left]);//输出中序串中叶子节点。
return;
}
for(mid=left;mid<=right;++mid)
{
if(s1[i]==s2[mid])//在中序中找到子树和树的根节点。
break;
}
++i; //i++中序与前序的下一个字母进行比较。
dfs(left,mid-1); //遍历左子树的左子树一直到最后一个左子树的叶子节点。
dfs(mid+1,right);//遍历右子树的右子树一直到最后一个右子树的叶子节点。
printf("%c",s2[mid]);//输出子树和树的根节点。
}
int main()
{
int root,l;
while(scanf("%s%s",s1,s2)!=EOF)
{
l=strlen(s1);
i=0;
dfs(0,l-1);
printf("\n");
}
return 0;
}
运行思路。
中序串 A B C D E F G
中序串和后序串的关系,中序串一般有左右孩子的话,都是左右孩子夹着根节点,而后序遍历从左孩子,到右孩子再根节点。
正好可以递归调用下面这三个方法。
dfs(left,mid-1); //遍历左子树的左子树一直到最后一个左子树的叶子节点。
dfs(mid+1,right);//遍历左子树的右子树一直到最后一个右子树的叶子节点。
printf("%c",s2[mid]);//输出子树和树的根节点。
1,首先根据前序串找到树的根节点(16-19行for循环) D 。
2,递归调用dfs(left,mid-1); 找到左子树的根节点 B。
3,再递归调用dfs(left,mid-1); 找到左子树的左孩子节点A 。(根据中序串AB,若是右孩子应该是BA。B是左子树的根节点)。
4,这时候left ==right 输出A
5,调用dfs(mid+1,right); ,把左子树根节点B的右节点打印出来 C。
6,输出mid(mid就相当根节点的位置。),返回上一级。。。再继续
这里一个重要的输出,条件是left==right,为什么这里要输出呢?
因为mid就是中序串中根节点的位置。mid前面为左孩子,右边为右孩子。。
而递归左子树方法 dfs(left,mid-1);
和递归右子树的方法 dfs(mid+1,right);
里面的实参正好使left==right。
而后序遍历从左孩子,到右孩子再根节点。完美的递归。。
orz大神。。。