二叉树的概念
- 导读
- 一、二叉树的定义及其主要特性
- 1.1 二叉树的定义
- 1.2 二叉树的主要特性
- 二、特殊的二叉树
- 2.1 满二叉树
- 2.2 完全二叉树
- 2.3 二叉排序树
- 2.4 平衡二叉树
- 三、二叉树的性质
- 3.1 性质一
- 3.2 性质二
- 3.3 性质三
- 3.4 性质四
- 3.5 性质五
- 结语
导读
大家好,很高兴又和大家见面啦!!!
在上一篇的内容中,我们介绍了树的一些基本概念、重要术语以及树的基本性质。通过上一篇内容的学习,相信大家都已经对树这种数据结构有了一个初步认识,并且能够区分度为m的树与m叉树。
要进一步的认识树这种数据结构的话,我们还是需要从逻辑结构、存储结构以及数据的运算三要素出发,来逐步认识树。
从今天的内容开始,我们将以二叉树这种特殊的树形结构为例,来逐步学习数据结构的三要素。下面我们就来开始进入的内容吧!!!
一、二叉树的定义及其主要特性
二叉树是一种特殊的树形结构,其特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且二叉树的子树有左右之分,其次序不能任意颠倒。
1.1 二叉树的定义
与树相似,二叉树也是以递归的形式定义。二叉树是 n ( n > = 0 ) n(n>=0) n(n>=0)个结点的有限集合:
- 当 n = 0 n=0 n=0时,为空二叉树;
- 当 n > 0 n>0 n>0时,二叉树由一个根结点和两棵互不相交的子树组成。这两棵子树分别存在于根结点的左右两侧,因此被称为左右子树。而左子树和右子树又分别是一棵二叉树。
这里我们需要注意的是二叉树的左右子树可以都为空子树,也可以是其中一棵为空子树,如下所示:
对于m叉树而言,树中的所有结点的度都是<=m,同理,二叉树中,所有结点的度都是<=2,因此二叉树中每一个结点作为根组成的树都是二叉树。
1.2 二叉树的主要特性
二叉树这种特殊的树形结构,它具有以下独有的特性:
- 二叉树的组成有三个部分,从左到右依次是:左子树、根结点、右子树;
- 二叉树的左右次序是确定的,并且二叉树的左右子树不能进行互换,因此二叉树是一棵有序树;
- 二叉树结点的度<=2,因此二叉树可以为空树;
- 二叉树的左右子树也是二叉树;
与二叉树比较相似的就是度为2的有序树,其基本形态如下所示:
由上图可知,其基本特性可总结为以下几点:
- 度为2的有序树的组成部分有两部分:分支结点(度>0的结点)、叶结点(度=0的结点);
- 度为2的有序树的左右次序是相较于另一个孩子而言,因此当树中存在度为1的结点时,该结点的孩子结点没有左右之分;
- 度为2的有序树中至少要有一个度为2的结点,因此其结点数量最少为3;
- 度为2的有序树中并不是所有结点的度都为2,因此其子树可能是度为1的树和度为0的树;
由此我们可以看到这二者的区别有以下几点
- 组成部分不同:二叉树是根据结点的位置划分为3部分:左子树、根结点和右子树;度为2的树则根据结点的度划分为2部分:分支结点和叶结点;
- 结点数量不同:二叉树中结点数量可以为0,即二叉树可以为空树;度为2的树中最少要有一个结点的度为2,因此度为2的树的结点最少为3;
- 子树的性质不同:二叉树的子树同样也是二叉树;度为2的子树可以是度为0的树、度为1的树和度为2的树;
二、特殊的二叉树
在了解了二叉树的定义和基本特性之后,下面我们来看一下几种特殊的二叉树;
2.1 满二叉树
**定义:**一棵高度为h,且含有 2 h − 1 2^h-1 2h−1个结点的二叉树称为满二叉树。即树中的每层都含有最多的结点,如下所示:
在满二叉树中,除了最后一层的叶结点的结点度数为0以外,其余的结点度数都为2,因此我们不难得到第一个结论:
- 高为h的满二叉树中有 2 h − 1 2^{h-1} 2h−1个叶结点,有 2 h − 1 − 1 2^{h-1}-1 2h−1−1个度为2的结点;
如果我们给满二叉树中的各个结点编上号,并约定从根结点开始自上而下,从左到右对每个结点进行由小到大的编号,这时我们就会得到如下二叉树:
这里我们以从1开始对二叉树进行编号,不难得到上述二叉树。通过观察不难发现满二叉树的父结点与子结点之间的编号关系:
- 对于编号为i的结点,如果有双亲,则双亲的结点编号为 i / 2 i/2 i/2 结果向下取整;如果有孩子,则左孩子的编号为 2 i 2i 2i,右孩子的编号为 2 i + 1 2i+1 2i+1;
如果从0开始对二叉树进行编号,我们则可以得到下面的二叉树:
可以看到,此时对于结点编号为i的结点,其父结点与孩子结点的结点编号的关系为:
- 若有父结点,则父结点编号为 ( i − 1 ) / 2 (i-1)/2 (i−1)/2 结果向下取整;若有孩子结点,则左孩子的结点编号为 2 i + 1 2i+1 2i+1 ,右孩子的编号为 2 i + 2 2i+2 2i+2 ;
这两种编号方式及其结论我们先要对其有个初步印象,不需要死记硬背,在后续的内容中,我们会进一步加深其理解。
2.2 完全二叉树
**定义:**高度为h、有n个结点的二叉树,当且仅当其每个结点都与高度为h的满二叉树中编号为1~n的结点一一对应是,称为完全二叉树。
完全二叉树单看其定义的话不是那么容易理解,下面我换一种简单的方式来进一步说明。
满二叉树指的是每一层的结点数量都是最大值,即高度为 h h h 的满二叉树第 i i i 层共有 2 i − 1 2^{i-1} 2i−1个结点;
完全二叉树指的是高度为 h h h 的满二叉树的最后一层的右侧可能缺失结点,即 n h ∈ [ 1 , 2 h − 1 ] n_h ∈ [1,2^{h-1}] nh∈[1,2h−1]
下面我们通过图像来进一步的理解,如下所示:
对于高度为h完全二叉树而言,它具有以下特性:
- 从第1层到第h-2层的结点的度为2;
- 从第1层到第h-1层的结点总数为 2 n − 1 − 1 2^{n-1}-1 2n−1−1;
- 第h层的结点数 n h ∈ [ 1 , 2 h − 1 ] n_h∈[1,2^{h-1}] nh∈[1,2h−1];
- 若存在度为1的结点,则该结点有且只有1个,其孩子结点一定是左孩子且该结点位于 h − 1 h-1 h−1层,其孩子位于第h层;
- 完全二叉树中的叶结点只存在于第h层以及 h − 1 h-1 h−1 层的右侧;
当我们将其从1开始进行编号时,我们不难得到以下二叉树:
从图中可以 看到,编号为13的结点只有左孩子,并且所有大于13的结点全部都是叶节点;而对于14号结点而言,它本身就是叶结点,从图中可以看到,所有编号大于14的结点均为叶结点;因此我们不难得到一个新的结论:
- 对于高度为h的完全二叉树,当编号为i的结点只有左孩子或者该结点为叶结点时,编号大于i的结点均为叶结点;
在上图展示的完全二叉树中,结点总数为26个,从编号中我们不难发现,编号为1~13的结点均为分支结点,而14~26的结点均为叶结点,;
当我们将26号结点去掉时,此时结点总数变成了25,对应的父结点编号为12,此时可以看到所有结点编号不超过12的结点均为分支结点,而所有编号大于12的结点均为叶结点因此我们还可以的到一个结论:
- 当结点的编号i满足 i < = n / 2 i<=n/2 i<=n/2 时,对应编号的结点均为分支结点,而 i > n / 2 i>n/2 i>n/2 的结点,均为叶结点;
那如果是从0开始编号又会如何呢?如下所示:
可以看到,此时该完全二叉树的结点总数为26,编号为12的结点只有左孩子,所有编号大于12的结点均为叶结点,所有编号不超过12的结点均为分支结点。因此前面得到的结论在这里也同样适用只不过稍有不同,如下所示:
- 当对高度为h的完全二叉树,从0开始进行编号时,对于结点编号i满足 i < = ( i − 1 ) / 2 i<=(i-1)/2 i<=(i−1)/2 向下取整的所有结点均为分支结点,而满足 i > ( i − 1 ) / 2 i>(i-1)/2 i>(i−1)/2向下取整的所有结点均为叶结点;
其实不管是从0开始编号还是从1开始编号,只要是对于结点数为n的完全二叉树,当对树中的结点从上到下,从左到右依次进行从小到大的编号时,结点的编号一定满足下列结论:
- 对于最后一个结点n而言,所有编号不大于其父结点的编号的结点均为分支结点,所有编号大于其父结点编号的结点均为叶结点;
细心的朋友会发现对于结点数为n的完全二叉树,还有一条非常重要的结论:
- 当n为偶数时,最后一个结点一定是左孩子,其父结点的度一定为1;
- 当n为奇数时,最后一个结点一定是右孩子,树中不存在度为1的结点;
完全二叉树的相关结论对我们后面的学习会非常重要,因此,建议大家熟读一下这些结论,当然,不建议大家死记硬背。如果在考试时遇到了这些问题,完全可以现场将这些结论通过画图推导出来,大家只要理解这些结论是如何得到的即可。
2.3 二叉排序树
定义:左子树上的所有结点的关键字均小于根结点的关键字;右子树上的所有结点的关键字均大于根结点的关键字;左子树和右子树又各是一棵二叉排序树。
二叉排序树(Binary Search Tree)又称为二叉搜索树或者二叉查找树,英文缩写为BST
。这个树在后面的学习中也是一个需要重点关注的树,这里我们同样是对其简单的做个介绍。
BST
的定义中所提到的关键字,和我们在C语言中学习的关键字是有区别的,我们目前可以简单的理解为就是二叉树的各个结点中存储的内容。在BST
中结点存储的内容满足左子树<根结点<右子树,以整型为例,如下所示:
在上图中我们不难发现,在BST
中如果一个结点存在左孩子,那么左孩子中存储的内容一定小于该结点存储的内容,如果该结点存在右孩子,则右孩子中存储的内容一定大于该结点存储的内容,如果同时存在左右孩子,那么结点中存储的内容一定满足左孩子<该结点<右孩子。
对于BST的详细内容在后面的篇章中我们会进一步介绍,目前大家只需要知道有这种特殊的二叉树即可。
2.4 平衡二叉树
定义:树上任意结点的左子树和右子树的深度之差不超过1。
平衡二叉树(Balanced Binary Tree)又称为AVL
树。这是由Georgy Maximovich Adelson-Velsky和Evgenii Mikhailovich Landis两位大佬提出来的,因此就由这两位大佬的名字中的AV和L共同为该二叉树进行的命名。感兴趣的朋友可以点击AVL Trees来了解大佬们提出AVL
Trees的事情经过。
下面我简单的说明一下什么事AVL树,如下图所示:
可以看到,在上述例子中每个结点的左右子树深度的差值的绝对值都不会超过1,这种就是AVL
树,对于AVL
树的相关内容,我们同样会在后面的篇章中详细的介绍,目前大家只需要了解即可。
三、二叉树的性质
在二叉树中有一些比较重要的性质需要我们有所了解,下面我们就来一一介绍这些性质的相关内容。
3.1 性质一
非空二叉树上的叶结点数等于度为2的结点数加1,即 n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1。
这条性质的证明比较简单,下面我们先介绍通过计算来证明该性质,如下所示:
- 设二叉树中度为0、度为1和度为2的结点数分别为 n 0 n_0 n0、 n 1 n_1 n1、 n 2 n_2 n2,则我们可以得到二叉树中的总结点数为 n = n 0 + n 1 + n 2 n = n_0+n_1+n_2 n=n0+n1+n2;
- 通过树的性质——树的结点数为所有度数之和加1,我们可以得到 n = 0 × n 0 + 1 × n 1 + 2 × n 2 + 1 n=0×n_0+1×n_1+2×n_2+1 n=0×n0+1×n1+2×n2+1;
- 联立两式可得: n 0 + n 1 + n 2 = n 1 + 2 × n 2 + 1 n_0+n_1+n_2 = n_1+2×n_2+1 n0+n1+n2=n1+2×n2+1;
- 通过移项可得: n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1;证明完毕。
接下来我们再来介绍通过特殊二叉树来证明该性质,如下所示:
- 以高度为h的满二叉树为例,在满二叉树中,叶结点只存在于第h层,且h层的结点数量为最大值,因此其叶结点的数量为 n 0 = 2 h − 1 n_0 = 2^{h-1} n0=2h−1 ;
- 满二叉树的第1层到第h-1层的结点的度都为2,因此度为2的结点总数为 n 2 = 2 h − 1 − 1 n_2=2^{h-1}-1 n2=2h−1−1;
- 由两式联立可得: n 2 = n 0 − 1 n_2=n_0-1 n2=n0−1;
- 再对其移项可得: n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1;证明完毕。
对于二叉树的共同性质,我们可以通过特殊二叉树来进行推导,但是这种方式只适用于选择填空题我们在忘记该性质内容时,如果是证明题还是得采用第一种方式来证明。
3.2 性质二
非空二叉树上第k层上至多有 2 k − 1 2^{k-1} 2k−1个结点。
这一条性质是由树的性质进行进一步推导得到的。在介绍树的性质时,我们有介绍过度为m的树的第i层的结点数最多有 m i − 1 m^{i-1} mi−1个。对于二叉树而言,这里的m=2,我们将其代入即可得到该性质。由于上一篇内容有详细证明,这里我就不再多加赘述。
3.3 性质三
高度为h的二叉树至多有 2 h − 1 ( h > = 1 ) 2^h-1(h>=1) 2h−1(h>=1)个结点。
这一条性质同样也是从树的性质进一步推导得到的。在介绍树的性质时,我们还介绍过对于高度为h的m叉树至多有 n = ( m h − 1 ) / ( m − 1 ) n=(m^h-1)/(m-1) n=(mh−1)/(m−1)个结点。对于二叉树而言,m=2,我们将其代入即可得到该性质。上一篇内容同样也有详细证明,这里我就不再多加赘述。
3.4 性质四
对于完全二叉树按从上到下,从左到右的顺序依次编号1,2,3……,n,则有以下关系:
- 当 i > 1 i>1 i>1 时,结点i的双亲的编号为 i / 2 (向下取整) i/2(向下取整) i/2(向下取整),即当 i i i 为偶数时,其双亲结点编号为 i / 2 i/2 i/2,该结点为左孩子;当 i i i 为奇数时,其双亲结点编号为 ( i − 1 ) / 2 (i-1)/2 (i−1)/2,该结点为右孩子;
- 当 2 i < = n 2i<=n 2i<=n 时,结点 i i i的左孩子编号为 2 i 2i 2i ,否则无左孩子。
- 当 2 i + 1 < = n 2i+1<=n 2i+1<=n 时,结点 i i i的右孩子编号为 2 i + 1 2i+1 2i+1,否则无右孩子。
- 结点 i i i 所在的层次(深度)为 h = l o g 2 i + 1 (向下取整) h=log_2i+1(向下取整) h=log2i+1(向下取整);
注意,这里的关系是从1开始进行编号,因此当我们从0开始编号时,对应的关系是会发生变化的,这里我们主要介绍这些关系的推导过程。
关系1——结点 i i i 的编号与其双亲结点的关系
在介绍完全二叉树时我们有提到过对于结点 i i i 而言,如果有父结点则父结点编号满足:
- 当从1开始编号时,其父结点的编号为 i / 2 (向下取整) i/2(向下取整) i/2(向下取整);
- 当从0开始编号时,其父结点的编号为 ( i − 1 ) / 2 (向下取整) (i-1)/2(向下取整) (i−1)/2(向下取整);
根据编号的不同,结点 i i i 的奇偶性所决定结点 i i i 的位置也有区别:
- 当从1开始编号时,若 i i i 为偶数,则该结点为左孩子,若 i i i 为奇数则该结点为右孩子;
- 当从0开始编号时,若 i i i 为奇数,则该结点为左孩子,若 i i i 为偶数则该结点为右孩子;
关系2、3——结点 i i i 的编号与其孩子结点的关系
在不同方式的编号中结点 i i i 的左右孩子编号也不相同:
- 当从1开始编号时,结点 i i i 的左孩子若存在,则其编号为 2 i 2i 2i;右孩子若存在,则其编号为 2 i + 1 2i+1 2i+1;
- 当从0开始编号时,结点 i i i 的左孩子若存在,则其编号为 2 i + 1 2i+1 2i+1;右孩子若存在,则其编号为 2 i + 2 2i+2 2i+2;
这里需要注意的是判断左右孩子是否存在,依据就是其左右孩子的编号不能超过结点的最大编号。
关系4——结点 i i i 的编号与其深度的关系
由于完全二叉树的特殊性,每一个结点的结点编号都是从第一层到该结点的最大结点编号,因此我们可以通过结点自身的编号获取从一层到该结点的结点总数:
- 当从1开始编号,从第一层到结点 i i i 的结点总数为 n = i n=i n=i;
- 当从0开始编号,从第一层到结点 i i i 的结点总数为 n = i + 1 n=i+1 n=i+1;
对于高度为h的完全二叉树而言,其结点总数最少为 n = 2 h − 1 n=2^{h-1} n=2h−1(详细证明见性质五);
因此联立上式可得:
- 当从1开始编号,结点 i i i 的所在层次为 h = l o g 2 i + 1 (向下取整) h=log_2i+1(向下取整) h=log2i+1(向下取整);
- 当从0开始编号,结点 i i i 的所在层次为 h = l o g 2 ( i + 1 ) + 1 (向下取整) h=log_2(i+1)+1(向下取整) h=log2(i+1)+1(向下取整);
3.5 性质五
具有 n ( n > 0 ) n(n>0) n(n>0)个结点的完全二叉树的高度为 h = l o g 2 ( n + 1 ) (向上取整) h=log_2(n+1)(向上取整) h=log2(n+1)(向上取整) 或 h = l o g 2 n + 1 (向下取整) h=log_2n+1(向下取整) h=log2n+1(向下取整)。
高度为h的完全二叉树的结点总数n = 每一层的结点数之和,即 n = n 1 + n 2 + … … + n h − 1 + n h (下标 h 为结点层次) n=n_1+n_2+……+n_{h-1}+n_h(下标h为结点层次) n=n1+n2+……+nh−1+nh(下标h为结点层次)
对于高度为h的完全二叉树而言,除了第h层,其余每一层的结点数都是 2 i − 1 ( 1 < = i < = h − 1 ) 2^{i-1}(1<=i<=h-1) 2i−1(1<=i<=h−1);
联立两式,我们不难得到结点总数为:
n
=
2
0
+
2
1
+
…
…
+
2
h
−
2
+
n
h
n=2^0+2^1+……+2^{h-2}+n_h
n=20+21+……+2h−2+nh
当高度为h的完全二叉树的结点总数最少时,即
n
h
=
1
n_h=1
nh=1,此时我们不难得到结点总数为:
n
=
2
0
+
2
1
+
…
…
+
2
h
−
2
+
1
n=2^0+2^1+……+2^{h-2}+1
n=20+21+……+2h−2+1
根据等比数列的求和公式我们就能得到: n = 2 h − 1 n=2^{h-1} n=2h−1;
当高度为h的完全二叉树的结点总数最多是,即
n
h
=
2
h
−
1
n_h=2^{h-1}
nh=2h−1,此时我们不难得到结点总数为:
n
=
2
0
+
2
1
+
…
…
+
2
h
−
2
+
2
h
−
1
n=2^0+2^1+……+2^{h-2}+2^{h-1}
n=20+21+……+2h−2+2h−1
根据等比数列的求和公式我们就能得到:
n
=
2
h
−
1
n=2^h-1
n=2h−1;
那对于结点数量为n的完全二叉树,其结点数量一定是位于最少与最多之间,因此我们可以得到不等式: 2 h − 1 < = n < = 2 h − 1 2^{h-1}<=n<=2^h-1 2h−1<=n<=2h−1
对不等式两边分别求解我们不难得到 h > = l o g 2 n + 1 h>=log_2n+1 h>=log2n+1 和 h < = l o g 2 ( n + 1 ) h<=log_2(n+1) h<=log2(n+1) ;
将该不等式改写成等式我们就得到了:
h = l o g 2 n + 1 (向下取整) h=log_2n+1(向下取整) h=log2n+1(向下取整) 和 h = l o g 2 ( n + 1 ) (向上取整) h=log_2(n+1)(向上取整) h=log2(n+1)(向上取整)。证明完毕。
对于二叉树的性质证明整体来说还是比较简单的,从整个证明的过程我们不难发现,这些性质都是基于树的性质进行的进一步推导,而对于完全二叉树的相关性质,我们借助图像的话能够更加容易的对其进行理解。因此在学习二叉树的过程中,建议大家遇到问题时,多画图,通过图像来帮助自己解决问题。
结语
今天的内容咱们就介绍到这里。在今天的内容中,我们知道了什么是二叉树,以及二叉树的一些基本性质,我们还认识了4种特殊的二叉树——满二叉树、完全二叉树、BST和AVL树。在接下来的内容中,我们同样会从数据结构的三要素出发进一步介绍二叉树这种数据结构,大家记得关注哦!!!
咱们今天的内容到这里就全部结束了,如果大家喜欢博主的内容,可以点赞、收藏加评论三连支持一下,当然也可以转发给身边需要的朋友。最后感谢各位的支持,咱们下一篇再见!!!