其实这道题,就是给出树的中序遍历和前序遍历,让你写出他的后续遍历哈哈
话说这道题跟之前的有点像啊。。
思路就是递归
别忘了左右边界的变化,上次你在这栽了坑
递归函数,
1.前序左端点找到根节点
2.中序序列之中找到根节点,记录其坐标
3.根据中序序列坐标和左右端点,计算左右子树长度,找到左坐标范围
4.在前序序列中找到找到左右子树的坐标范围
5.左子树递归,右子树递归
6.打印根节点
7.结束
递归结束条件。
左右端点相等,说明只剩一个点了
好吧,看来又出现了我最害怕的逻辑出错了,这些下标算起来真是有点烦人
而且终止条件看起来很难判断啊。。
重要的错误!:
对于我的递归学习有很大的帮助
对于递归中的变量,如果需要记录,那么请把变量设置成全局变量
但是如果有多次连续递归都需要用到一个变量,并且需要这个变量只在这层递归有效,那么请设置在这个函数内部
比如这道题中的root和proot
由于下面有左右子树的双层递归,如果设在外面,那么左子树递归之后,再return回来的时候,
root和proot就不是原来的值了!
当然我们纠结的递归终止条件,就是
if(左>=右)
{
if(左==右)
{
输出
}
return 0;
/即可/
}
附代码:
#include<stdio.h>
#include<string.h>
char midt[27],head[27];
int length=0;
void dfs(int ml,int mr,int hl,int hr);
int main()
{
scanf("%s",midt);
scanf("%s",head);
length=strlen(midt);
dfs(0,length-1,0,length-1);
return 0;
}
void dfs(int ml,int mr,int hl,int hr)
{
char root;
int proot=0;
if(ml>mr||hl>hr)
{
return ;
}
if(ml==mr||hl==hr)
{
printf("%c",midt[ml]);
return ;
}
root=head[hl];//取出根节点
for(int i=ml;i<=mr;i++)
{
if(midt[i]==root)
{
proot=i;//找到根节点的位置
break;
}
}
//计算左右子树的下标.然后进行递归
// printf("dfs(%d,%d,%d,%d):\n",ml,proot-1,hl+1,hl+proot-ml);
// printf("proot=%d,ml=%d,mr=%d,hl=%d,hr=%d\n",proot,ml,mr,hl,hr);
// printf("当前根节点:%c\n",midt[proot]);
dfs(ml,proot-1,hl+1,hl+proot-ml);
// printf("dfs(%d,%d,%d,%d)\n",proot+1,mr,hl-ml+proot+1,hr);
// printf("当前根节点:%c\n",midt[proot]);
// printf("proot=%d,ml=%d,mr=%d,hl=%d,hr=%d\n",proot,ml,mr,hl,hr);
dfs(proot+1,mr,hl+proot-ml+1,hr);
printf("%c",root);
return ;
}