问题分析:已知一颗二叉树S的前序遍历和中序遍历序列,请编程输出二叉树S的后续遍历序列。
(举例:pre[]/先序:A、B、D、E、C、F、G; in[]/中序:D、B、E、A、C、G、F; 后序遍历序列是:D、E、B、G、F、C、A)
#include<stdio.h>
#include<string.h>
//在中序序列中查找根节点下标的函数,函数参数为:根节点符号,中序序列,中序序列起始下标,中序序列结束下标
int findroot(char c,char in[],int in_s,int in_e)
{
int i;
for(i=in_s;i<=in_e;i++)
{
if(in[i]==c) //若在中序序列中找到根节点的符号,则退出循环,返回下标
break;
}
return i;
}
// 递归求后序序列的函数,函数参数分别为:先序序列、先序序列起始下标、先序序列结束下标、中序序列、中序序列起始下标、中序序列结束下标
void postorder(char pre[],int pre_s,int pre_e,char in[],int in_s,int in_e)
{
char c; //根节点符号
int root; //根节点在中序中的下标
int l_len,r_len; //左、右子树节点数
if(in_s==in_e) //如果中序序列只有一个节点,那么当前二叉树只有一个节点,直接输出
{
printf("%c",in[in_s]);
}
else //如果中序序列不止一个节点
{
c=pre[pre_s]; //根节点为先序序列的第一个节点
root=findroot(c,in,in_s,in_e); //获取根节点在中序序列的下标
//计算左、右子树的节点数
l_len=root-in_s;
r_len=in_e-root;
if(l_len>0) //如果左子树节点数大于0,递归处理左子树
{
postorder(pre,pre_s+1,pre_s+l_len,in,in_s,root-1); //第二个参数为pre_s+1是因为先序序列的第二个节点是根节点左子树的根
}
if(r_len>0) //如果右子树节点数大于0,递归处理右子树
{
postorder(pre,pre_s+l_len+1,pre_e,in,root+1,in_e); //第二个参数为pre_s+l_len+1是因为在先序遍历中根节点和左子树节点的后一个节点是右子树节点的根
}
printf("%c",c); //最后后序输出根节点c
}
}
int main()
{
char pre[]="ABDECFG"; //先序序列
char in[]="DBEACGF"; //中序序列
postorder(pre,0,strlen(pre)-1,in,0,strlen(in)-1);
printf("\n");
return 0;
}