已知先序遍历和中序遍历 如何求后序遍历?

本文详细介绍了如何通过先序和中序遍历的序列来推导出后序遍历的序列,并通过具体代码实例进行了解释。包括遍历过程的解析和代码实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先序遍历,可记做根左右(二叉树父结点向下先左后右)。
首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树,如果二叉树为空则返回。
中序遍历,左根右。后序遍历,左右根。
 
那已知先序遍历和中序遍历 如何求后序遍历?
举个例子:先序遍历:ABDCF,中序遍历DBAFC。首先先序遍历,根左右,第一个元素必为根节点,则A为根节点。再看中序,左根右,根据A在中序的位置,可知左子树为DB,右子树为FC。然后递归求解DB和FC。先序,B为除去A的第一个元素,即为左子树根。中序,DB,则D为B左。同理,C为根,F为左子树。所以,树为:
 
 
 
 
通过上面总结步骤如下:
①确定树的根节点。通过先序遍历最先出现的元素。
②通过根节点分出左右子树。通过查找根节点在中序中的位置来分出左右子树。
③重复①②步骤,知道求解完成。
 
具体代码如下:
 
int initTree(Tree *root,char *front,char *middle,int num)
{
        in i=0;
        root->data = front[0];
        if(num==0) return 0;//全部结束
        //找到根节点在middle中的位置
        for(i=0;i<num;i++)
        {
                     if(middle[i]==root->data) break;
       }
       //如果root存在左子树
      if(i!=0)
      {
           root->lchild=new struct TreeNode();
           initTree(root->lchild,front+1,middle,i);
     }
    if(i!=num-1)
   {
           root->rchild = new struct TreeNode();
           initTree(root->rchild,front+i+1,middle+i+1,i);
    }
    return 1;
}

 

下面分析下以上代码,用前面的例子,先序遍历:ABDCF,中序遍历DBAFC:

1、第一层,

先序遍历:A B D C F,

                       ↑                                                

i=0,root->data=front[0]='A',

找A在middle中位置,for(---)  i=2,

因为i!=0,所以,产生新节点,

递归左子树,front+1,

 

2、第二层,第一层:A左分支,num=2

先序: B D  C F ,

            ↑                                                                 

root->data = front[0]='B'

找B在middle中位置,for(---)  i=1,

因为i!=0,所以,产生新节点,

递归左子树,front+1,

 

3、第二层:B 的左分支:,num=1

先序: D  C F ,

            ↑                                                            

root->data = front[0]='D'

找D在middle中位置,for(---)  i=0,

不满足i!=0,也不满足i!=num-1(此时,i=0,num=1)

所以return 1,至 2、第二层

 

4、返回到了上一层:第二层:B,                                                 

此时i=1,num=3

所以不满足if(i!=num-1)

所以return 1,至 1、第一层:A

 

5、第一层:A,i=2,num=5

因为满足if(i!=num-1)

产生新节点,

递归右子树,front+i+1,middle+i+1(即front+3,middle+3,即C,F)

 

6、第一层A的右分支,第二层,num=2

先序:  C F ,      后序:F C 

            ↑                          ↑                      

 

root->data=front[0]='C'

找C在middle中位置,for(---)  i=1,                 

满足if(i!=0)

产生新节点,

递归左子树,front+1,middle

 

8、第二层的左分支,第三层,num=1

先序: F , 后序:F C 

            ↑                 ↑       

root->data=front[0]='F'

找F在middle中位置,for(---)  i=0,

不满足if(i!=0),不满足if(i!=num-1)

返回至上一层C,第6步

 

9、C右子树,

此时i=1,num=2,

不满足if(i!=num-1)

所以return 1,至 1、第一层。

 

return 1

程序结束.

 

通过以上分析,可以看出i与0,num-1的关系所代表的的意义

i:找字符在middle中位置,

而i代表包含当前节点左子树的个数,

若i==0,则说明该节点无左子树。

num代表所以节点个数,

如果i==num-1,则说明该节点在中序遍历时已经是最后一个节点,所以无右子树。

 

该方法的缺点:没有对越界的判断,

 

 

 

 

                           

 

 

 

 

 

 

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值