【题意简述】:此题大概意思就是给你一颗二叉树的前序遍历序列和一棵树的中序遍历序列,现在让你求出这棵树的后序遍历序列。
【思路】:最近老师 让我们做这道题,遂来解题。了解题意后不难建立解题思路,我的想法是这样的由前序和中序可以构建此树,然后输出此树的后序遍历序列便不是问题。但如果我们知道后序序列的特征(顺序是这样的:1、后序遍历根节点的左子树;2、后序遍历根节点的右子树;3、访问根节点),就可以直接写出结果,因为每一次可以看到,前序和中序遍历恰好与后序的特征相反,依照这一特征,我们便可以在通过前序和中序(递归)构建这棵树的过程中,将节点存入栈中,后进先出,输出此后序遍历序列!
这个是我们老师讲课时的幻灯片,遍历的过程分享给大家!
下面代码注释是我从别人看来的:
由于t1,r1为前序遍历,所以dlr[t1]必为该子树的根节点,因此在ldr的区间段[t2,r2]中查找与根节点相同的字符,设索引为k。
若k>l2,说明左子树存在,节点有leftsize=k-l2个。
中序遍历中[t2,k-1]为该左子树的遍历结果,前序遍历中[t1+1,t1+a]为左子树的遍历结果,然后递归。
若k>r2,说明右子树存在。
中序遍历中[k+1,r2]为该右子树的遍历结果,前序遍历中[t1+a+1,r1]为右子树的遍历结果,然后递归。
最后输出该树的根节点dlr[t1]或者ldr[k]。
/* 136K 0Ms */
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int maxn = 30;
int len;
char dlr[maxn], ldr[maxn]; //dlr: 前序遍历的序列。ldr: 中序遍历的序列
/*
l1,r1:前序遍历的区间段
l2,r2:中序遍历的区间段
这两个区间对应的是同一颗子树
*/
void dfs(int t1,int r1,int t2,int r2)
{
int k; //k作为索引;
for(int i = t2;i<=r2;i++)
{
if(dlr[t1]==ldr[i])
{
k = i;
break;
}
}
int leftsize = k - t2;// 左子树大小
if(k > t2)
{
dfs(t1+1,t1+leftsize,t2,k-1);
}
if(k < r2)
{
dfs(t1 + leftsize+1,r1,k+1,r2);
}
printf("%c",dlr[t1]); //输出根节点!
}
int main()
{
while(scanf("%s%s",dlr,ldr) != EOF)
{
len = strlen(dlr);
dfs(0,len-1,0,len-1);
printf("\n");
}
return 0;
}