题目描述
给出一棵二叉树的前序遍历序列和中序遍历序列,根据前序和中序序列还原二叉树之后,得到二叉树的后序遍历序列
输入
两个字符串,其长度n均小于等于26。
第一行为前序遍历,第二行为中序遍历。
二叉树中的结点名称以大写字母表示:A,B,C…最多26个结点。
输出
输入样例可能有多组,对于每组测试样例,
输出一行,为后序遍历的字符串。
样例输入
ABC
CBA
ABCDEFG
DCBAEFG
GDAFEMHZ
ADEFGHMZ
样例输出
CBA
DCBGFEA
AEFDHZMG
解题思路
前序遍历第一个节点肯定是子树的根节点,在中序遍历中寻找这个节点head,假设找到位置为i,那么i前面就是以head为根节点的左子树,i后面就是以head为根节点的右子树。前序和中序遍历得到的两个字符串s1,s2的长度均为len,那么就可以把s1划分为两部分左子树(s1,1,i)【因为s1的第一个节点就是根节点,使用了就要丢掉】右子树(s1,i+1,len-1)【这一块就是右子树】。同理将s2划分成(s2,0,i-1)和(s2,i+1,len-1)两部分。s1[0]就是后序遍历的s3[len-1] 【因为后序遍历最后遍历根节点,s1的第一个节点就是s3的最后一个节点】。在此,再把s3也划分成两部分(s3,0,i-1)和(s3,i,(len-1)-1)。然后采取不断递归,就可以得到后序遍历的字符串。(具体实现看代码吧)
为什么用数组
一般都会采用建树,然后再遍历就好了,用数组只是我觉得数组代码简单,可以少打一些字,然后看起来也比较清楚,再而就是节省空间还能省掉最后遍历的那个过程,因为数组再还原树的时候就已经是在遍历了。
如果对你有用,随便留点评论吧,感觉自己的博客好冷清哦,从今天开始学习Java,每一阶段学习心得和怎么学的也一起发到博客来
#include
#include
#include
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define req(i, a, b) for(int i=(a); i<=(b); i++)
#define reps(i, a, b) for(int i=(a); i>(b); i--)
#define reqs(i, a, b) for(int i=(a); i>=(b); i--)
#define ull unsigned __int64
#define sc(t) scanf("%d",&(t))
#define sc2(t,x) scanf("%d%d",&(t),&(x))
#define pr(t) printf("%d\n",(t))
#define pf printf
#define prk printf("\n")
#define pi acos(-1.0)
#define ms(a,b) memset((a),(b),sizeof((a)))
#define mc(a,b) memcpy((a),(b),sizeof((a)))
#define w while
#define vr vector
#define gr greater
typedef long long ll;
//reverse 将字符串转置
//map<,>::iterator it
//FILE *fp, *os;
char pre[30], mid[30], post[30];
int len;
void _post(int l1,int r1,int l2,int r2,int l3,int r3)
{
//puts("aaa");
//printf("post[%d] = pre[%d] = %c\n",r3, l1,pre[l1]);
post[r3] = pre[l1];
if(l1 == r1)
return;
int pos = 0;
req(i, l2, r2)
{
pos++;
if(pre[l1] == mid[i])
{
break;
}
}
//post[r3] = pre[l1];
//printf("l1 = %d r1 = %d l2 = %d r2 = %d l3 = %d r3 = %d pos = %d\n",l1,r1,l2,r2,l3,r3,pos);
if(l1+1<=l1+pos-1 && l1+pos-1<=r1)
_post(l1+1,l1+pos-1,l2,l2+pos-2,l3,l3+pos-2);
if(l1+pos<=r1)
_post(l1+pos,r1,l2+pos,r2,l3+pos-1,r3-1);
}
int main()
{
// fp = fopen("","w+");
// os = fopen("","r+");
// ifstream in("fp.txt");
// ofstream out;
// out.open("res.txt");
w(~scanf("%s",pre))
{
scanf("%s",mid);
int len = strlen(pre);
//printf("len = %d\n",len);
_post(0,len-1,0,len-1,0,len-1);
post[len] = '\0';
printf("%s\n",post);
}
return 0;
}