根据给定的前序遍历与中序遍历能够唯一确定后序遍历
题目来源:牛客网
- 题目
- 题目分析
- 代码
- 测试结果
- 代码分析
题目分析:
给定一个例子:
前序:FDXEAG,
中序:XDEFAG
(1)由前序遍历可知,F为树的根结点,由中序遍历可知XDE为根结点F的左子树,AG为右子树
(2)由前序遍历可知,D为树XDE的根结点,由中序遍历可知X为结点D的左子树,E为右子树,同理可知A为树AG的根结点,G为右子树,无左子树
(3)在遍历的过程中可以设置一个树的长度变量,当树的长度为1时,输出该结点;
(4)由(1)(2)可知,此题用递归容易解决;
(5)因为后序遍历的顺序为:左右根,故递归遍历时应先遍历左子树,再遍历右子树,根据结束条件判断输出值
递归遍历的流程图如下:
代码:
#include<stdio.h>
#include<string.h>
void hoge(char *pre,char *in,int length){
char c=pre[0];
if(length == 0){
return;
}
if(length ==1){
printf("%c",c);
return;
}
int i=0;
while(in[i]!=c){
i++;
}
hoge(pre+1,in,i);
hoge(pre+i+1,in+i+1,length-1-i);
printf("%c",c);
}
int main(){
char pre[30],in[30];
int length;
while(scanf("%s%s",pre,in)!=EOF){
length = strlen(pre);
hoge(pre,in,length);
}
return 0;
}
测试结果:
代码分析:
(1)定义了一个递归函数hoge
(2)因为题目中给出字符串长度小于26,故定义了两个字符数组,长度大于26;
(3)题目中要求测试多组数据,故用while(scanf("%s%s",pre,in)!=EOF)来判断;
(4)注意字符串输入时的语句:scanf("%s%s",pre,in);
(5)递归函数hoge代码分析:
1)定义一个字符型变量c,将前序遍历的第一个字符(即树的根结点)赋值给c;
2)定义整型变量i,i从0开始,依次遍历中序遍历中的字符,看是否等于c,这一步是找到根结点在中序遍历中的位置,从而可以找到根的左子树与右子树
int i=0;
while(in[i]!=c){
i++;
}
3)找到左子树与右子树 后依次递归遍历,先遍历左子树,遍历的过程即可将左子树的全部结点输出,同理右子树;
因为传递给hoge函数的三个参数,分别为指向前序遍历的指针,指向中序遍历的指针,树的长度
因为pre[0]为树的根结点,所以指向左子树时要将pre+1,in一直为第一个字符,根据2)可知,左子树的长度为i
右子树先序遍历的指针分别为pre+i+1,in+i+1,这里in+i+1的原因为in+i为左子树的长度,再加一个根结点,右子树的长度为length-i-1
hoge(pre+1,in,i);
hoge(pre+i+1,in+i+1,length-1-i);
4)左右子树依次遍历后输出根结点