大家好!这里是小张,上次我们说到了二叉树的存储结构,今天我们继续来说说二叉树的遍历,废话不多说,我们现在就开始!
另外有很多小伙伴们在学习算法的时候,只去学习一些关于算法理论的知识,并不知道自己的代码实战能力如何,也不清楚到底对该算法的了解有多深,所以在这里小张给大家推荐一个很棒的平台,在这里有很多的面试和算法题,也有很多的面试和求职的机会,大家可以点击下方链接进入牛客网刷算法真题,提高自己代码实战能力,早日拿到满意的offer!
点击这里进入牛客网刷算法面试真题提高实战能力
遍历的目的
首先我们先来说说遍历二叉树,那么什么叫做遍历二叉树呢,遍历就是说顺着某一条路径进行巡防,二叉树中的结点,使二叉树中每一个结点都被访问一次,而且只被访问一次(可以之间理解成把二叉树中的每一个结点按一定顺序都访问一次)。
那么我们为什么要进行二叉树的遍历操作呢,是因为二叉树的遍历操作是树结构进行插入,删除,修改,查找和排序运算的前提,是二叉树进行一切运算的基础和操作的核心。
最后遍历的目的何在,它的目的就是能够使二叉树的所有结点能够组成一个线性的排列。
遍历的方法----先序遍历
下面我们来说说遍历的方法,遍历的方法理论上有很多种,只要能够把二叉树上的每一个结点都访问一次的遍历方法都可以。但是我们现在一般规定先访问左孩子,再访问右孩子,那么现在遍历的方法缩小到了三种,它们分别是,先序遍历,中序遍历以及后序遍历。那么先序,中序,后序,它们的差别在哪里呢,它们的差别其实仅仅是访问的顺序不太一样,其中先序遍历是先进行访问根结点,再去访问左孩子,右孩子。中序遍历则是先去访问左孩子,再去访问根结点,右孩子。同理后序遍历是先访问左孩子,右孩子,再去访问根结点。
如下图所示:
下面我们先来说说先序遍历:
由于我们现在研究的是二叉树,而二叉树中每一个结点都是由根结点,左孩子,右孩子组成的所以我们就可以运用递归的方法进行遍历二叉树。
(1) 访问根结点
(2) 先序访问左孩子
(3) 先序访问右孩子
例如这个最简单的二叉树,如果我们进行先序遍历,那么它就会先访问根结点A,再访问最孩子B,最后来进行访问右孩子C。
下面我们来看一下稍微复杂一点的二叉树
看到了这个复杂点的二叉树我们不要害怕,按照我们的方法一步一步来,所有的问题都会迎刃而解。首先我们按照方法三步走,第一步访问根结点A,再去访问左孩子B。又因为左孩子B又是一个根结点,那么我们现在以B作为根结点继续按照方法三步走,第一步访问根结点B,再去访问左孩子E。这时我们发现E还是一个根结点,那么我们继续按照方法三步走,去访问E的左孩子。这时我们发现E没有左孩子,不要慌,要是它没有左孩子的话,我们就继续按照方法去访问它的右孩子L。此时L又又又又是一个根结点,继续按照方法三步走(根结点,左孩子,右孩子),发现L没有左孩子和右孩子,那么我们就把A的左孩子部分遍历完啦!此时我们先稍微总结一下,此时的遍历顺序为A,B,E,L。
下面进行A右孩子的遍历,右孩子看起来比左孩子要复杂,但是原理还是一样的,我们先来访问D,此时D是一个根结点**(一旦我们遇到了根结点就要按照我们的方法进行三步走)**,此时已经访问过D了,我们再来进行访问D的左孩子H,此时H又是一个根结点,我们再继续根据方法三步走,去访问它的左孩子M,此时M还是一个根结点,我们继续访问M的左孩子,右孩子,发现都为空,此时M的整个结点已经全部访问完毕。我们接着去访问呢H的右孩子I发现I的左孩子和右孩子都为空,那么我们现在的I结点也已经访问完毕。此时要进行D结点右孩子的访问,进入到J发现J的左孩子和右孩子都为空,那么J结点访问呢完毕,至此,该二叉树的所有结点全部访问完毕,先序遍历完成,此时A的右孩子的遍历结果为D,H,M,I,J。
我们现在进行总结一下整个二叉树的遍历结果为A,B,E,L,D,H,M,I,J,要是我们按照方法三步走,是不是感觉也不是很难理解,好啦,到这里我们的先序遍历就进行完啦!
遍历的方法----中序遍历
下面我们来说说中序遍历:
(1) 中序访问左孩子
(2) 访问根结点
(3) 中序访问右孩子
还是这个最简单的二叉树,我们要是进行先序遍历进行访问的话,按照我们的方法三步走,那么此时的遍历顺序就先是左孩子B,再是跟结点A,最后是右孩子C。
下面我们来继续对这个稍微复杂点的二叉树进行中序遍历**(这里由于我们刚刚的先序遍历已经把方法阐述过了,所以现在我们就只说访问左孩子的一边)**按照方法我们先进行左孩子B的访问,发现B此时是一个根结点,那么我们就先不管它,继续按照方法访问它的左孩子E。此时发现E还是一个根结点,那么我们继续先不管E继续访问它的左孩子,此时我们发现E没有左孩子那么我们就返回到E,进行访问E,再进入到E的右孩子里去访问L。此时B的左孩子部分已经全部遍历完成,此时再去访问B,之后按照方法再去访问B的右孩子,发现B没有右孩子,那么此时B结点全部访问完成,此时A结点的左孩子部分已经全部遍历完成,再去访问A,此时的遍历顺序为E,L,B,A,此时遍历的前两步已全部进行完成,最后一步就留给大家去练习一下。我先把最后遍历完的顺序告诉大家,大家写完之后可以对比一下,顺序为E,L,B,A,M,H,I,D,J。
到这里我们的中序遍历也已经进行完啦,我们接着进行后序遍历。
遍历的方法----后序遍历
下面是后续遍历:
(1) 后序访问左孩子
(2) 后序访问右孩子
(3) 访问根结点
还是这个最简单的二叉树,我们要是进行后序遍历进行访问的话,按照我们的方法三步走,那么此时的遍历顺序就先是左孩子B,再是跟结点A,最后是右孩子C。
我们继续来看这个稍微复杂点的二叉树,这里我们就不进行详细的介绍啦,大家可以根据上面的先序遍历和中序遍历的方法结束来自行的进行后序遍历的操作。在这里我先把比遍历的结果告诉大家,方便大家进行对比,后序遍历的结果是L,E,B,M,I,H,J,D,A 。
到这里我们的后序就已经全部进行完啦,下面我们来说说由遍历结果来推出二叉树。
由遍历结果来推出二叉树
由遍历结果推二叉树
我们现在由由遍历结果来推出二叉树的类型有两种,一种是已知先序遍历和中序遍历推出二叉树,第二种是由后序遍历和中序遍历推出二叉树结果,那么为什么不可以由先序遍历和后序遍历推出二叉树结果呢,小张在这里先卖个关子,大家听完小张说完这两种类型之后自然就明白啦!
第一种,已知先序遍历和中序遍历,构造出相应的二叉树:
先序:A,B,C,D,E,F,G,H,I,J
中序:C,D,B,F,E,A,I,H,G,J
我们遇见这样的类型题目时候不要慌,牢牢记住一句话**——前后定跟,中分左右——**,意思是我们可以根据先序或者后序遍历确定根结点是哪个,再通过中序遍历确定左孩子和右孩子。
首先我们先来看这个类型,我们可以根据先序遍历看出来此时的跟为A,再根据中序遍历确定左孩子为C,D,B,F,E,右孩子为I,H,G,J。同理我们再根据先序遍历知道了此时的A的第一个左孩子为B,则B就为根结点,再看中序遍历,发现此时B左边的孩子为C,D右边的孩子为F,E。再根据先序遍历可得出C为根结点,再看中序遍历此时C的左边没有元素,那么可得C没有左孩子,右孩子为D。再回到B,发现B的右孩子为F,E。根据先序遍历发现E为根结点,再看中序遍历发现E有左孩子为F。此时A的左孩子全部访问完成,A的右孩子按照以上方法继续进行访问即可。
最后结果如下图所示:
到这里就已经把先序遍历和中序遍历的类型说完啦,下面进行中序遍历和后序遍历的类型:
中序序列:B,D,C,E,A,F,H,G
后序序列:D,E,C,B,H,G,F,A
看到这里不要慌,使用方法——前后定跟,中分左右——,此时进行的方法和上面的已知先序遍历和中序遍历的方法一样,这里就不在详细说了,大家可以自己画一画,下面是画完之后的结果。
文章来源:https://www.toymoban.com/news/detail-497062.html
到了这里我想大家也都能明白了为什么已知先序遍历和后序遍历画不出一个二叉树,是因为我们根本无法从先序遍历和后序遍历中确定谁是根谁是左右孩子,这样的话我们的方法就无法使用,所以是无法画出一个二叉树的。
到了这里今天博客的所有内容都已经说完啦,我们会注意到今天的二叉树的遍历其实就是很多次套娃,一个里面套着一个,只要我们一个一个进行分析,所有问题就会迎刃而解。如果小张有哪里出错或者不足的地方,欢迎大家到评论区进行留言,小张都会进行一一回复,争取下次进行改正。此外,二叉树系列持续更新中,希望大家可以多多支持小张,小张提前在这里谢谢大家啦!
文章来源地址https://www.toymoban.com/news/detail-497062.html
到了这里,关于一文搞懂二叉树遍历---超详解(二叉树逐步剖析二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!