灵魂之问:二叉树的前中后序遍历,你真的掌握了吗?

废话不多说,先上图,请你写出下面这一个二叉树的后序遍历序列。

image.png

正确答案是:8,7,6,5,4,3,2,10,15,14,13,12,11,9,1。你答对了吗?

如果没有答对,看来你还是没掌握二叉树的深度优先遍历啊(摊手)。今天就来一起详细剖析,二叉树的前中后序遍历,到底是个啥?

引入:首先二叉树的遍历分为深度优先遍历和广度优先遍历。

广度优先遍历:一层一层地去遍历,一层访问完再访问下一层。也叫层次遍历。

深度优先遍历:令无数同学糊涂的遍历方式。又分为前、中、后序遍历。

这里直接奉上结论:前、中、后,指的是子树根节点在子树遍历中的顺序。

前序遍历:先访问根节点、再访问左子树、最后访问右子树。(根、左、右)

中序遍历:先访问左子树、再访问根节点、最后访问右子树。(左、根、右)

后序遍历:先访问左子树、再访问右子树、最后访问根节点。(左、右、根)

你就发现了,哦,原来前序指的就是根节点在前(根、左、右),中序指的就是根节点在中(左、根、右),后续指的就是根节点在后(左、右、根)

那么关于上面的那个图,就这样来遍历: 

注:为了方便,在下面的叙述中我们把以节点2为根节点的子树,叫做“2子树”,望读者知悉。

image.png

1.后序遍历以1为根的树,要先后序遍历其左子树——2子树。

2.要后序遍历2子树,就要先后序遍历其左子树——3子树。

3.要后序遍历完3子树,就要先遍历完其左子树(为空,所以左子树遍历就完成了)。

4.3子树的左子树遍历完成,要遍历完3子树,就要再遍历完其右子树——4子树。

(这里的遍历均指后序)

5.要遍历完4子树,就要先遍历完其左子树(为空,遍历完成),再遍历完其右子树——5子树。

6.要遍历完5子树,就要先遍历完其左子树——6子树。

7.要遍历完6子树,就要先遍历完其左子树——8子树。

8.要遍历完8子树,就要依次遍历其左、右、根;8子树左右均为空,左右遍历完成,遍历根节点,于是后序序列出现了第一个数字:8。

9.遍历8节点后,8子树遍历完成。在步骤(7)中,要遍历完6子树,要先遍历完左子树(8子树)和右子树(7子树),最后遍历根节点6。所以接着遍历7子树。

10.7子树左右子树均为空,遍历根节点7,7子树遍历完成,后序序列更新为:8,7。

11.依(步骤9),遍历根节点6,6子树遍历完成,后序序列更新为8,7,6;

12.依(步骤6),5子树的左子树(6子树)遍历完成。5子树的右子树为空。故遍历根节点5,后序序列更新为8,7,6,5;

13.依(步骤5),4子树的右子树遍历完成,因为要遍历4子树,故遍历根节点4,后序序列:8,7,6,5,4;

14.依(步骤4),3子树的右子树遍历完成,故遍历根节点3,后序序列:8,7,6,5,4,3;

15.依(步骤2),2子树的左子树遍历完成,要遍历完2子树就要遍历其右、根;右子树为空,遍历根节点2,后序序列:8,7,6,5,4,3,2;

16.依(步骤1),树1的左子树遍历完成,要遍历完树1就要遍历右、根;开始遍历树1的右子树......

至此,1的左子树遍历完成。

下面是遍历右子树的简写:要遍历9子树,就等价于:遍历10子树、遍历11子树、遍历节点9。10子树是叶子节点左右均为空,故遍历根节点10,10子树遍历完成;后序序列:8,7,6,5,4,3,2,10;10子树遍历完成,就要开始遍历11子树。要遍历11就要先遍历12,要遍历12就要先遍历13,要遍历13就要先遍历15——15遍历完成,后序序列加上15;要遍历13还要再遍历完14——14遍历完成,后序序列加上14;要遍历13还要再遍历13根节点——13子树遍历完成,后序序列加上13;12左右子树遍历完成,加上12;11左右子树遍历完成,加上11;9的左右子树遍历完成,加上9;9子树遍历完成,1的左右子树就遍历完成。要遍历完树1,只需再遍历根节点1,加上1。终后序序列:8,7,6,5,4,3,2,10,15,14,13,12,11,9,1。完全正确。

其实刚才你所看到的文字描述,就是递归的过程。还是记住那句话:

前序遍历:(根、左、右)

中序遍历:(左、根、右)

后序遍历:(左、右、根)

你理解了吗?

补充:通过中序和后序序列恢复二叉树

现在给你中序序列 3,4,8,6,7,5,2,1,10,9,11,15,13,14,12;

后序序列 8,7,6,5,4,3,2,10,15,14,13,12,11,9,1;

让你画出二叉树的结构图。这又该怎么做呢?

第一轮:

1.后序遍历是左、右、根,所以二叉树的根节点在最后,根节点为1;

2.找到根节点1在中序序列中的位置。中序遍历是啥来着?左、根、右。左子树的元素全部在序列中根节点位置的左侧,右子树的元素全部在序列中根节点位置的右侧。由此将中序序列划分为[3,4,8,6,7,5,2],1,[10,9,11,15,13,14,12],括号代表左右子树的圈定。注意此时已经可以确定左右子树元素个数为7,7。

3.回到后序遍历得到的序列8,7,6,5,4,3,2,10,15,14,13,12,11,9,1。后序序列遍历是啥来着?左、右、根。先遍历左子树(也是后序遍历),再后序遍历右子树。左子树的所有元素在序列中的位置都位于右子树元素之前,也就是左子树元素在序列最前方。根据中序序列,我们得出:左子树有7个元素;那么在后序序列中,前七个元素就是左子树元素。那么后序序列划分为:[8,7,6,5,4,3,2] , [10,15,14,13,12,11,9] , 1。(左、右、根)

第一轮后,能确定的树结构如下:

image.png

 

第二轮:[8,7,6,5,4,3,2] , [10,15,14,13,12,11,9] , 1中,[8,7,6,5,4,3,2]是后序遍历左子树得到的序列。

[3,4,8,6,7,5,2],1,[10,9,11,15,13,14,12]中,[3,4,8,6,7,5,2]就是中序遍历左子树得到的序列。

把左子树看做一颗单独的树,我们就已经得到了该树的中序和后序遍历序列。所以仍然按照上面的逻辑,后序遍历该树得到序列【8,7,6,5,4,3,2】,可得出2是该树的根节点。回到该树的中序遍历序列【3,4,8,6,7,5,2】,根据中序遍历左、根、右的顺序,划分中序序列为[3,4,8,6,7,5],2,[ ],所以2这颗子树的左子树有6个元素,右子树为空。回到后序遍历上,因为左子树有6个元素,所以就是[8,7,6,5,4,3],[ ], 2。第二轮结束后树的结构如下:(下图方框内数字排序无实际意义)

image.png

第三轮 :在第二轮中我们又得到了2树的左子树的后序遍历序列[8,7,6,5,4,3]和中序遍历序列[3,4,8,6,7,5],所以根节点为3,又推导出中序[],3,[4,8,6,7,5],后序[],[8,7,6,5,4],3,依此类推......

经过很多轮后得到如下树的结构:

image.png

类似的,根据前序、中序遍历一棵二叉树得到的序列也可以还原树的结构。

但是根据前、后序则无法还原。

前序:1,2,3,4,5,6,8,7,9,10,11,12,13,15,14

后序:8,7,6,5,4,3,2,10,15,14,13,12,11,9,1。

在前序和后序序列中,我们唯一只能知道根节点为1,但是从哪里开始区分左子树元素和右子树元素我们是不知道的。因此前、后序不能还原二叉树。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值