导读
信息学能够有助于孩子未来工作发展,提升孩子的综合能力。
这一节课,我们走进树形结构的世界,了解树的基本理论,了解二叉树的相关概念和性质,学习二叉树的存储、遍历方式。最后我们简单了解森林的基本知识以及森林和二叉树的相关转换。
1 树结构引入
在我们前面讲数据结构的时候,我们讲过四种结构:
我们当时还画了他们的图,其中树形结构的图如下:
今天,我们来具体看一下树形结构的内容。
2 树
树是一对多的结构,相比一对一线性结构,更加复杂,考虑的内容也比较多!
1 什么是树
树(tree)T是一个包含n(n>=0)个数据元素的有限集合。并且:
2 树的相关术语
树有很多重要的概念:
结点:树上的一个点,包含一个数据元素及若干指向其子树的分支。
结点的度(Degree):结点拥有的子树的个数。
叶子(Leaf)或终端结点:度为0的结点(没有子结点的结点)。
分支结点或非终端结点:度不为0的结点。
树的度:树内各结点的度的最大值。
孩子(child)(子结点):结点的子树的根称为该结点的孩子
双亲(Parent)(父结点):结点是其子结点的双亲结点。
兄弟(Sibling):同一双亲的孩子之间互称为兄弟。
祖先:结点的祖先是从该结点所经分支上的所有结点。
子孙:以某结点为根的子树中的任一结点都称为该结点的子孙。
层次(Level):从根开始定义起,根为第一层,根的孩子为第二层。双亲在同一层的结点互为堂兄弟。
树的深度(Depth):树中结点的最大层次称为树的深度或高度。
有序树:若将树中的结点的各子树看成从左至右是有次序的(即不能互换)则称该树为有序树。
3 树的表示方法
树的表示方法,主要有:
对于下面这棵树,这种方法叫一般表示。我们针对不同的方法可以有不同的表示:
1、嵌套集合
嵌套集合就是双亲结点中会包含所有的孩子结点。图示如下:
2、广义表
广义表是通过括号将子结点包含在一起:
3、凹入表示
凹入表示,其实就是对子结点加缩进。注意,同一层次的结点,缩进相同。
3 二叉树
树中最重要的就是二叉树!
1 二叉树的定义
二叉树也是树,不过有两条限制:
2 二叉树的几种形态
二叉树主要有如下几种形态:
其中:
3 二叉树的性质
二叉树的性质是树理论中,最重要的!
性质1:有n(n>0)个结点的二叉树的分支数为n-1。
证明:对于每个结点,除了根结点外,剩余的所有结点都是其父结点的分支。也就是除根结点外的n-1个结点,都是分支。所以分支数为n-1。
注:这个性质也可以这么理解,有n个结点的树,有n-1条边,这个因为,除根结点之外,剩下所有结点都有一条边指向其父结点。
性质2:若二叉树的高度为h(h≥0),则该二叉树最少有h个结点,最多有
证明:二叉树最少结点是每一层只有一个结点,一共有h层,一共有h个结点。最多情况,每一层都满了,对于第i层,有 。所以有h层,就一共有:
性质3:含有n个结点的二叉树的高度最大值为n,最小值为
证明:因为在二叉树中,每层至少有一个结点,因此对于含有n个结点的二叉树,其高度不会超过n。根据性质2可以得知,高度为h的二叉树最多有 个结点,即 ,因此 。由于h是整数,所以 。
性质4:具有 n 个结点的完全二叉树的高度为 。
证明:性质4其实就是性质3的推广。高度最小时,就是完全二叉树。
性质5:如果将一棵有n个结点的完全二叉树自顶向下,同一层自左向右连续给结点编号0、1、2、…、n-1。则第i个结点的左孩子结点的编号是 ,右孩子结点的编号是 。
证明:这道题最好的证明方式就是通过画图,总结规律:
这些性质会在竞赛中考到,这些也只是基本性质,考试中会有各种变形。
4 二叉树的存储结构
二叉树在使用过程中,一般有两种方法,一种是顺序结构存储,一种是链式结构存储。
1、数组表示法
顺序结构存储,就是我们要将二叉树存在数组中,这个时候,存放的位置,就是二叉树中结点对应到满二叉树对应位置的索引:
这样的话,我们就可以随机访问每个元素,也可以非常方便的插入和删除树上的结点。但是这种做法可能会非常浪费空间。如果树中结点特别少,但是树的高度特别高,就会有很多浪费。
2、二叉链表表示法
二叉链表表示法是为了解决上面浪费空间的问题,二叉链表需要存放当前结点的数据和两个指向其左右子结点的指针。如果没有对应子结点,就把这个指针设为空。
这种方法需要多少个结点就申请多少个空间。不会造成浪费,但是他会引入链表本身的缺点,不支持随机访问。
3、三叉链表表示法
三叉链表和二叉链表理论完全一致,区别就在于,多了一个指向其父结点的指针。对于根结点来说,一般将其父结点指向自己,所以当我们判断什么是根结点的时候,我们就判断其父结点指针是否指向了自己。
5 二叉树的遍历
1、总述
二叉树有四种遍历。
前三个特别好记,先序、中序和后序强调的是根的访问顺序:
如果先访问根,后访问左右,访问顺序就是根左右,这个叫先序遍历;
如果先访问左,中间访问根,最后访问右,访问顺序就是左根右,这个叫中序遍历;
如果先访问左右,最后访问根,访问顺序就是左右根,这个叫后序遍历。
在具体的过程中,这个过程是递归实现的。例如对于下面的树:
2、先序遍历
先序遍历和我们的常识很像,先访问根结点,然后进入到左子树,访问左子结点,访问完左子结点,就访问右子结点。
遍历顺序为:A、B、D、E、G、H、C、F、I。
3、中序遍历
中序遍历是先访问左,我们可以这样理解。在每个结点的左子树的,都在其左边,在每个结点右子树的,都在其右边,当我们把所有的这些结点看做同一层的时候,从左往右就可以了。例如上面的图,我们可以变为如下:
然后我们按照从左到右的顺序排列:
所以中序遍历为:D、B、G、E、H、A、C、F、I。
4、后序遍历
后序遍历就需要我们认真分析了。后序遍历要先访问左子结点,再访问右子结点,最后访问根结点。当然我们还是要先从根结点出发。
想访问根结点,要先访问左子树,再访问右子树。最后访问根结点。所以顺序为:
对于左右子树结点,还是按照上面的原则:
对于B:
到这里,B的已经有序:
对于C:
到这里,C的已经有序:
回到A:
这个还不是最难的,最难的是根据两种遍历方式,求另一种遍历方式。
5、根据两种遍历求另一种遍历序列
例如:
注:不能通过二叉树的先序和后序遍历得到其中序遍历。这是因为,当访问过程中,根不在中间时,某个结点只有一个子结点的时候,我们就不能区分这个结点到底是左子结点还是右子结点了。
这种题目,我们要先根据两种遍历恢复二叉树,然后再获取第三种遍历方式。举个例子:
先序+中序->后序
就以我们上面的为例:
我们知道,先序的第一个是这个树的根结点。然后我们在中序中找A,将中序分为左右两部分,然后我们要在这个时候写对应的后序,只需要考虑当前部分是按照左右根的顺序就可以了:
对于先序的每一部分,第一个都是当前子树的根结点,然后我们再在中序中对应部分,使用根结点将左右分开。
然后再分,单个的就不用再分了:
这个时候,每个结点都单独分开了。然后我们就可以考虑后序了,只需要去掉括号就可以了:
中序+后序->先序
然后我们再来看
我们知道,后序的最后一个是这个树的根结点。然后我们在中序中找A,将中序分为左右两部分,然后我们要在这个时候写对应的先序,只需要考虑当前部分是按照根左右的顺序就可以了:
对于后序的每一部分,最后一个都是当前子树的根结点,然后我们再在中序中对应部分,使用根结点将左右分开。
然后再分,单个的就不用再分了:
这个时候,每个结点都单独分开了。然后我们就可以考虑先序了,只需要去掉括号就可以了:
6、层次遍历
层次遍历就是按照深度从上往下,按照左右从前往后遍历。上面的那个层次遍历如下:
4 森林
然后我们看一下森林!
1 什么是森林
森林:是m(m≥0)棵互不相交的树的集合;不同的树,有自己的根结点,一个森林中,至少有两个树,也就是至少有两个根结点。如图所示:
这是有两棵树的森林。
2 二叉树与森林的转换
森林中最重要的森林和二叉树的转换:
森林变为二叉树,有如下两个原则:
简单来说就是:左孩子还是左孩子,右兄弟变成右孩子。
例如下面这个森林:
转换为二叉树如下:
二叉树转回森林,跟上面的过程是相反的,左孩子还是左孩子,右孩子变成右兄弟。
6 作业
本节课的作业,就是复习上面的所有知识,并完成下面的竞赛真题!
1 NOIP2011年提高组真题
1、(单选题)右图是一棵二叉树,它的先序遍历是( )
2、(不定项选择)如果根结点的深度记为1,则一棵恰有2011 个叶子结点的二叉树的深度可能是( )
2 NOIP2018提高组真题
1、(单选题)设根节点深度为0,一棵深度为h的满k(k>1)叉树,即除最后一层无任何子节点外,每一层上的所有结点都有k个子结点的树,共有( )个结点:
2、(不定项选择)2-3 树是一种特殊的树,它满足两个条件:
如果一棵2-3 树有10 个叶结点,那么它可能有( )个非叶结点。
AI与区块链技术
长按二维码关注