Morris先序中序遍历

Morris先序中序遍历

这里把Morris实现先序中序遍历放在一起记录是因为先序和中序原理相同。这两者都和各自的递归版本有着很强的联系性。

实现原理

在上一节Morris遍历文章中,阐述了递归的本质。再来熟悉下:

递归实现前中后序遍历二叉树的算法非常简单,但是深入探究背后,会发现三者其实是统一的。为什么这么说,这是因为三者的递归序是一样的,而且每个非空节点都被访问了3次,而不同的是打印的行为发生在递归序当中的第几次,这就造就了3中不同序的遍历。

而且也阐述了Morris遍历的本质,如下:

Morris遍历是在高度模仿递归,其本质为任何一个有左子树的节点可以访问2次,否则只能访问1次。相比较于递归来说,它无法在访问完右子树后回到当前节点。

先序遍历

在Morris序中对于有左子树的节点来说,第一次访问时打印,没有左子树的节点碰到就打印。

中序遍历

在Morris序中对于有左子树的节点来说,第二次访问时才打印,没有左子树的节点碰到就打印。

疑问

对于有左子树的节点来说先序和中序很好理解,因为和递归的理解是一样的,但是为什么对于没有左子树的节点来说先序和中序一样呢。
其实不妨这样看,Morris遍历时,对于没有左子树的节点,先访问自己一次,然后访问自己的左子树,然后又回到自己。其实这两次访问重合到一起了,所以Morris遍历省去了遍历空树的过程,把没有左子树的节点的两次访问合并为1次,所以不管是先序和中序,碰到没有左子树的节点就打印,其实逻辑上打印的不是同一个值。
举例:6202434568789这是某个二叉树遍历的Morris序,根据本质可以分析出没有左子树的节点分别是0,3,5,7,9。其实逻辑上Morris序应该是620024334556877899,对于0节点,先序遍历,逻辑上应该是索引2号位置的值,中序遍历逻辑上应该是3号索引位置的值。但是真实的处理当中对于没有左子树的节点我们只访问了一次,把两次合并成1次了,由于这两次访问时相邻的,所以并不影响正确性。

总结

通过本文,可以等得到Morris遍历的逻辑本质是每个非空节点都被访问了两次。但是由于没有左子树的节点两次访问相邻,可以合并为1次,所以它的本质在优化后就是上一节阐述的观点,对于所有非空的节点,没有左子树的节点只访问1次,而有左子树的节点可以访问两次。
Morris实现先序和中序遍历也和递归完全相同,递归是在递归中选择打印时机,而Morris是在Morriss序中选择打印时机。
Morris实现先序遍历和中序遍历的代码后续会添加到自动回复中。可以微信公众号后台输入“先序遍历”,“中序遍历”获得。

关于作者

大四学生一枚,分享数据结构,面试题,golang,C语言等知识。QQ交流群:521625004。微信公众号:后台技术栈。
image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值