二叉树的概念

【数据结构】树与二叉树——二叉树的概念_二叉树

导读

大家好,很高兴又和大家见面啦!!!

在上一篇的内容中,我们介绍了树的一些基本概念、重要术语以及树的基本性质。通过上一篇内容的学习,相信大家都已经对树这种数据结构有了一个初步认识,并且能够区分度为m的树与m叉树。

要进一步的认识树这种数据结构的话,我们还是需要从逻辑结构、存储结构以及数据的运算三要素出发,来逐步认识树。

从今天的内容开始,我们将以二叉树这种特殊的树形结构为例,来逐步学习数据结构的三要素。下面我们就来开始进入的内容吧!!!

一、二叉树的定义及其主要特性

二叉树是一种特殊的树形结构,其特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且二叉树的子树有左右之分,其次序不能任意颠倒。

1.1 二叉树的定义

与树相似,二叉树也是以递归的形式定义。二叉树是【数据结构】树与二叉树——二叉树的概念_C语言_02个结点的有限集合:

  1. 【数据结构】树与二叉树——二叉树的概念_数据结构_03时,为空二叉树;
  2. 【数据结构】树与二叉树——二叉树的概念_二叉树_04时,二叉树由一个根结点和两棵互不相交的子树组成。这两棵子树分别存在于根结点的左右两侧,因此被称为左右子树。而左子树和右子树又分别是一棵二叉树。

这里我们需要注意的是二叉树的左右子树可以都为空子树,也可以是其中一棵为空子树,如下所示:

【数据结构】树与二叉树——二叉树的概念_二叉树_05

对于m叉树而言,树中的所有结点的度都是<=m,同理,二叉树中,所有结点的度都是<=2,因此二叉树中每一个结点作为根组成的树都是二叉树。

1.2 二叉树的主要特性

二叉树这种特殊的树形结构,它具有以下独有的特性:

  1. 二叉树的组成有三个部分,从左到右依次是:左子树、根结点、右子树;
  2. 二叉树的左右次序是确定的,并且二叉树的左右子树不能进行互换,因此二叉树是一棵有序树;
  3. 二叉树结点的度<=2,因此二叉树可以为空树;
  4. 二叉树的左右子树也是二叉树;

与二叉树比较相似的就是度为2的有序树,其基本形态如下所示:

【数据结构】树与二叉树——二叉树的概念_C语言_06

由上图可知,其基本特性可总结为以下几点:

  1. 度为2的有序树的组成部分有两部分:分支结点(度>0的结点)、叶结点(度=0的结点);
  2. 度为2的有序树的左右次序是相较于另一个孩子而言,因此当树中存在度为1的结点时,该结点的孩子结点没有左右之分;
  3. 度为2的有序树中至少要有一个度为2的结点,因此其结点数量最少为3;
  4. 度为2的有序树中并不是所有结点的度都为2,因此其子树可能是度为1的树和度为0的树;

由此我们可以看到这二者的区别有以下几点

  1. 组成部分不同:二叉树是根据结点的位置划分为3部分:左子树、根结点和右子树;度为2的树则根据结点的度划分为2部分:分支结点和叶结点;
  2. 结点数量不同:二叉树中结点数量可以为0,即二叉树可以为空树;度为2的树中最少要有一个结点的度为2,因此度为2的树的结点最少为3;
  3. 子树的性质不同:二叉树的子树同样也是二叉树;度为2的子树可以是度为0的树、度为1的树和度为2的树;

二、特殊的二叉树

在了解了二叉树的定义和基本特性之后,下面我们来看一下几种特殊的二叉树;

2.1 满二叉树

**定义:**一棵高度为h,且含有【数据结构】树与二叉树——二叉树的概念_数据结构_07个结点的二叉树称为满二叉树。即树中的每层都含有最多的结点,如下所示:

【数据结构】树与二叉树——二叉树的概念_二叉树_08

在满二叉树中,除了最后一层的叶结点的结点度数为0以外,其余的结点度数都为2,因此我们不难得到第一个结论:

  • 高为h的满二叉树中有【数据结构】树与二叉树——二叉树的概念_数据结构_09个叶结点,有【数据结构】树与二叉树——二叉树的概念_数据结构_10个度为2的结点;

如果我们给满二叉树中的各个结点编上号,并约定从根结点开始自上而下,从左到右对每个结点进行由小到大的编号,这时我们就会得到如下二叉树:

【数据结构】树与二叉树——二叉树的概念_二叉树_11

这里我们以从1开始对二叉树进行编号,不难得到上述二叉树。通过观察不难发现满二叉树的父结点与子结点之间的编号关系:

  • 对于编号为i的结点,如果有双亲,则双亲的结点编号为 【数据结构】树与二叉树——二叉树的概念_数据结构_12 结果向下取整;如果有孩子,则左孩子的编号为 【数据结构】树与二叉树——二叉树的概念_C语言_13,右孩子的编号为 【数据结构】树与二叉树——二叉树的概念_二叉树_14

如果从0开始对二叉树进行编号,我们则可以得到下面的二叉树:

【数据结构】树与二叉树——二叉树的概念_数据结构_15

可以看到,此时对于结点编号为i的结点,其父结点与孩子结点的结点编号的关系为:

  • 若有父结点,则父结点编号为 【数据结构】树与二叉树——二叉树的概念_数据结构_16 结果向下取整;若有孩子结点,则左孩子的结点编号为 【数据结构】树与二叉树——二叉树的概念_二叉树_14 ,右孩子的编号为 【数据结构】树与二叉树——二叉树的概念_二叉树_18

这两种编号方式及其结论我们先要对其有个初步印象,不需要死记硬背,在后续的内容中,我们会进一步加深其理解。

2.2 完全二叉树

**定义:**高度为h、有n个结点的二叉树,当且仅当其每个结点都与高度为h的满二叉树中编号为1~n的结点一一对应是,称为完全二叉树。

完全二叉树单看其定义的话不是那么容易理解,下面我换一种简单的方式来进一步说明。

满二叉树指的是每一层的结点数量都是最大值,即高度为 【数据结构】树与二叉树——二叉树的概念_二叉树_19 的满二叉树第 【数据结构】树与二叉树——二叉树的概念_C语言_20 层共有 【数据结构】树与二叉树——二叉树的概念_数据结构_21个结点;完全二叉树指的是高度为 【数据结构】树与二叉树——二叉树的概念_二叉树_19 的满二叉树的最后一层的右侧可能缺失结点,即【数据结构】树与二叉树——二叉树的概念_C语言_23

下面我们通过图像来进一步的理解,如下所示:

【数据结构】树与二叉树——二叉树的概念_C语言_24

对于高度为h完全二叉树而言,它具有以下特性:

  1. 从第1层到第h-2层的结点的度为2;
  2. 从第1层到第h-1层的结点总数为 【数据结构】树与二叉树——二叉树的概念_二叉树_25
  3. 第h层的结点数 【数据结构】树与二叉树——二叉树的概念_数据结构_26
  4. 若存在度为1的结点,则该结点有且只有1个,其孩子结点一定是左孩子且该结点位于【数据结构】树与二叉树——二叉树的概念_数据结构_27层,其孩子位于第h层;
  5. 完全二叉树中的叶结点只存在于第h层以及 【数据结构】树与二叉树——二叉树的概念_数据结构_27 层的右侧;

当我们将其从1开始进行编号时,我们不难得到以下二叉树:

【数据结构】树与二叉树——二叉树的概念_C语言_29

从图中可以 看到,编号为13的结点只有左孩子,并且所有大于13的结点全部都是叶节点;而对于14号结点而言,它本身就是叶结点,从图中可以看到,所有编号大于14的结点均为叶结点;因此我们不难得到一个新的结论:

  • 对于高度为h的完全二叉树,当编号为i的结点只有左孩子或者该结点为叶结点时,编号大于i的结点均为叶结点;

在上图展示的完全二叉树中,结点总数为26个,从编号中我们不难发现,编号为1~13的结点均为分支结点,而14~26的结点均为叶结点,;当我们将26号结点去掉时,此时结点总数变成了25,对应的父结点编号为12,此时可以看到所有结点编号不超过12的结点均为分支结点,而所有编号大于12的结点均为叶结点因此我们还可以的到一个结论:

  • 当结点的编号i满足 【数据结构】树与二叉树——二叉树的概念_数据结构_30 时,对应编号的结点均为分支结点,而 【数据结构】树与二叉树——二叉树的概念_数据结构_31 的结点,均为叶结点;

那如果是从0开始编号又会如何呢?如下所示:

【数据结构】树与二叉树——二叉树的概念_数据结构_32

可以看到,此时该完全二叉树的结点总数为26,编号为12的结点只有左孩子,所有编号大于12的结点均为叶结点,所有编号不超过12的结点均为分支结点。因此前面得到的结论在这里也同样适用只不过稍有不同,如下所示:

  • 当对高度为h的完全二叉树,从0开始进行编号时,对于结点编号i满足 【数据结构】树与二叉树——二叉树的概念_数据结构_33 向下取整的所有结点均为分支结点,而满足 【数据结构】树与二叉树——二叉树的概念_数据结构_34向下取整的所有结点均为叶结点;

其实不管是从0开始编号还是从1开始编号,只要是对于结点数为n的完全二叉树,当对树中的结点从上到下,从左到右依次进行从小到大的编号时,结点的编号一定满足下列结论:

  • 对于最后一个结点n而言,所有编号不大于其父结点的编号的结点均为分支结点,所有编号大于其父结点编号的结点均为叶结点

细心的朋友会发现对于结点数为n的完全二叉树,还有一条非常重要的结论:

  • 当n为偶数时,最后一个结点一定是左孩子,其父结点的度一定为1;
  • 当n为奇数时,最后一个结点一定是右孩子,树中不存在度为1的结点;

完全二叉树的相关结论对我们后面的学习会非常重要,因此,建议大家熟读一下这些结论,当然,不建议大家死记硬背。如果在考试时遇到了这些问题,完全可以现场将这些结论通过画图推导出来,大家只要理解这些结论是如何得到的即可。

2.3 二叉排序树

定义:左子树上的所有结点的关键字均小于根结点的关键字;右子树上的所有结点的关键字均大于根结点的关键字;左子树和右子树又各是一棵二叉排序树。

二叉排序树(Binary Search Tree)又称为二叉搜索树或者二叉查找树,英文缩写为BST。这个树在后面的学习中也是一个需要重点关注的树,这里我们同样是对其简单的做个介绍。

BST的定义中所提到的关键字,和我们在C语言中学习的关键字是有区别的,我们目前可以简单的理解为就是二叉树的各个结点中存储的内容。在BST中结点存储的内容满足左子树<根结点<右子树,以整型为例,如下所示:

【数据结构】树与二叉树——二叉树的概念_数据结构_35

在上图中我们不难发现,在BST中如果一个结点存在左孩子,那么左孩子中存储的内容一定小于该结点存储的内容,如果该结点存在右孩子,则右孩子中存储的内容一定大于该结点存储的内容,如果同时存在左右孩子,那么结点中存储的内容一定满足左孩子<该结点<右孩子。

对于BST的详细内容在后面的篇章中我们会进一步介绍,目前大家只需要知道有这种特殊的二叉树即可。

2.4 平衡二叉树

定义:树上任意结点的左子树和右子树的深度之差不超过1。

平衡二叉树(Balanced Binary Tree)又称为AVL树。这是由Georgy Maximovich Adelson-Velsky和Evgenii Mikhailovich Landis两位大佬提出来的,因此就由这两位大佬的名字中的AV和L共同为该二叉树进行的命名。感兴趣的朋友可以点击AVL Trees来了解大佬们提出AVL Trees的事情经过。

下面我简单的说明一下什么事AVL树,如下图所示:

【数据结构】树与二叉树——二叉树的概念_数据结构_36

可以看到,在上述例子中每个结点的左右子树深度的差值的绝对值都不会超过1,这种就是AVL树,对于AVL树的相关内容,我们同样会在后面的篇章中详细的介绍,目前大家只需要了解即可。

三、二叉树的性质

在二叉树中有一些比较重要的性质需要我们有所了解,下面我们就来一一介绍这些性质的相关内容。

3.1 性质一

非空二叉树上的叶结点数等于度为2的结点数加1,即 【数据结构】树与二叉树——二叉树的概念_数据结构_37

这条性质的证明比较简单,下面我们先介绍通过计算来证明该性质,如下所示:

  1. 设二叉树中度为0、度为1和度为2的结点数分别为 【数据结构】树与二叉树——二叉树的概念_C语言_38【数据结构】树与二叉树——二叉树的概念_二叉树_39【数据结构】树与二叉树——二叉树的概念_二叉树_40,则我们可以得到二叉树中的总结点数为 【数据结构】树与二叉树——二叉树的概念_C语言_41
  2. 通过树的性质——树的结点数为所有度数之和加1,我们可以得到 【数据结构】树与二叉树——二叉树的概念_二叉树_42
  3. 联立两式可得: 【数据结构】树与二叉树——二叉树的概念_C语言_43
  4. 通过移项可得: 【数据结构】树与二叉树——二叉树的概念_数据结构_37;证明完毕。

接下来我们再来介绍通过特殊二叉树来证明该性质,如下所示:

  1. 以高度为h的满二叉树为例,在满二叉树中,叶结点只存在于第h层,且h层的结点数量为最大值,因此其叶结点的数量为 【数据结构】树与二叉树——二叉树的概念_二叉树_45
  2. 满二叉树的第1层到第h-1层的结点的度都为2,因此度为2的结点总数为【数据结构】树与二叉树——二叉树的概念_二叉树_46
  3. 由两式联立可得: 【数据结构】树与二叉树——二叉树的概念_数据结构_47
  4. 再对其移项可得: 【数据结构】树与二叉树——二叉树的概念_数据结构_37;证明完毕。

对于二叉树的共同性质,我们可以通过特殊二叉树来进行推导,但是这种方式只适用于选择填空题我们在忘记该性质内容时,如果是证明题还是得采用第一种方式来证明。

3.2 性质二

非空二叉树上第k层上至多有【数据结构】树与二叉树——二叉树的概念_二叉树_49个结点。

这一条性质是由树的性质进行进一步推导得到的。在介绍树的性质时,我们有介绍过度为m的树的第i层的结点数最多有 【数据结构】树与二叉树——二叉树的概念_数据结构_50个。对于二叉树而言,这里的m=2,我们将其代入即可得到该性质。由于上一篇内容有详细证明,这里我就不再多加赘述。

3.3 性质三

高度为h的二叉树至多有 【数据结构】树与二叉树——二叉树的概念_C语言_51个结点。

这一条性质同样也是从树的性质进一步推导得到的。在介绍树的性质时,我们还介绍过对于高度为h的m叉树至多有【数据结构】树与二叉树——二叉树的概念_二叉树_52个结点。对于二叉树而言,m=2,我们将其代入即可得到该性质。上一篇内容同样也有详细证明,这里我就不再多加赘述。

3.4 性质四

对于完全二叉树按从上到下,从左到右的顺序依次编号1,2,3……,n,则有以下关系:

  1. 【数据结构】树与二叉树——二叉树的概念_数据结构_53 时,结点i的双亲的编号为 【数据结构】树与二叉树——二叉树的概念_数据结构_54,即当 【数据结构】树与二叉树——二叉树的概念_C语言_20 为偶数时,其双亲结点编号为 【数据结构】树与二叉树——二叉树的概念_数据结构_12,该结点为左孩子;当 【数据结构】树与二叉树——二叉树的概念_C语言_20 为奇数时,其双亲结点编号为【数据结构】树与二叉树——二叉树的概念_数据结构_16,该结点为右孩子;
  2. 【数据结构】树与二叉树——二叉树的概念_数据结构_59 时,结点【数据结构】树与二叉树——二叉树的概念_C语言_20的左孩子编号为 【数据结构】树与二叉树——二叉树的概念_C语言_13 ,否则无左孩子。
  3. 【数据结构】树与二叉树——二叉树的概念_数据结构_62 时,结点【数据结构】树与二叉树——二叉树的概念_C语言_20的右孩子编号为 【数据结构】树与二叉树——二叉树的概念_二叉树_14,否则无右孩子。
  4. 结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 所在的层次(深度)为 【数据结构】树与二叉树——二叉树的概念_二叉树_66;

注意,这里的关系是从1开始进行编号,因此当我们从0开始编号时,对应的关系是会发生变化的,这里我们主要介绍这些关系的推导过程。

关系1——结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的编号与其双亲结点的关系

在介绍完全二叉树时我们有提到过对于结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 而言,如果有父结点则父结点编号满足:

  • 当从1开始编号时,其父结点的编号为 【数据结构】树与二叉树——二叉树的概念_数据结构_54
  • 当从0开始编号时,其父结点的编号为 【数据结构】树与二叉树——二叉树的概念_数据结构_70

根据编号的不同,结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的奇偶性所决定结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的位置也有区别:

  • 当从1开始编号时,若 【数据结构】树与二叉树——二叉树的概念_C语言_20 为偶数,则该结点为左孩子,若 【数据结构】树与二叉树——二叉树的概念_C语言_20 为奇数则该结点为右孩子;
  • 当从0开始编号时,若 【数据结构】树与二叉树——二叉树的概念_C语言_20 为奇数,则该结点为左孩子,若 【数据结构】树与二叉树——二叉树的概念_C语言_20 为偶数则该结点为右孩子;

关系2、3——结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的编号与其孩子结点的关系

在不同方式的编号中结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的左右孩子编号也不相同:

  • 当从1开始编号时,结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的左孩子若存在,则其编号为 【数据结构】树与二叉树——二叉树的概念_C语言_13;右孩子若存在,则其编号为【数据结构】树与二叉树——二叉树的概念_二叉树_14
  • 当从0开始编号时,结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的左孩子若存在,则其编号为 【数据结构】树与二叉树——二叉树的概念_二叉树_14;右孩子若存在,则其编号为 【数据结构】树与二叉树——二叉树的概念_二叉树_18

这里需要注意的是判断左右孩子是否存在,依据就是其左右孩子的编号不能超过结点的最大编号。

关系4——结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的编号与其深度的关系

由于完全二叉树的特殊性,每一个结点的结点编号都是从第一层到该结点的最大结点编号,因此我们可以通过结点自身的编号获取从一层到该结点的结点总数:

  • 当从1开始编号,从第一层到结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的结点总数为 【数据结构】树与二叉树——二叉树的概念_数据结构_87
  • 当从0开始编号,从第一层到结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的结点总数为 【数据结构】树与二叉树——二叉树的概念_二叉树_89

对于高度为h的完全二叉树而言,其结点总数最少为 【数据结构】树与二叉树——二叉树的概念_数据结构_90(详细证明见性质五);

因此联立上式可得:

  • 当从1开始编号,结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的所在层次为 【数据结构】树与二叉树——二叉树的概念_二叉树_66
  • 当从0开始编号,结点 【数据结构】树与二叉树——二叉树的概念_C语言_20 的所在层次为 【数据结构】树与二叉树——二叉树的概念_数据结构_94

3.5 性质五

具有【数据结构】树与二叉树——二叉树的概念_数据结构_95个结点的完全二叉树的高度为 【数据结构】树与二叉树——二叉树的概念_数据结构_96【数据结构】树与二叉树——二叉树的概念_C语言_97

高度为h的完全二叉树的结点总数n = 每一层的结点数之和,即 $$n=n_1+n_2+……+n_{h-1}+n_h(下标h为结点层次)$$

对于高度为h的完全二叉树而言,除了第h层,其余每一层的结点数都是【数据结构】树与二叉树——二叉树的概念_数据结构_98

联立两式,我们不难得到结点总数为:

【数据结构】树与二叉树——二叉树的概念_C语言_99

当高度为h的完全二叉树的结点总数最少时,即【数据结构】树与二叉树——二叉树的概念_二叉树_100,此时我们不难得到结点总数为:

【数据结构】树与二叉树——二叉树的概念_数据结构_101

根据等比数列的求和公式我们就能得到:【数据结构】树与二叉树——二叉树的概念_数据结构_90

【数据结构】树与二叉树——二叉树的概念_数据结构_103

当高度为h的完全二叉树的结点总数最多是,即【数据结构】树与二叉树——二叉树的概念_C语言_104,此时我们不难得到结点总数为:

【数据结构】树与二叉树——二叉树的概念_C语言_105

根据等比数列的求和公式我们就能得到:【数据结构】树与二叉树——二叉树的概念_二叉树_106

【数据结构】树与二叉树——二叉树的概念_数据结构_107

那对于结点数量为n的完全二叉树,其结点数量一定是位于最少与最多之间,因此我们可以得到不等式:【数据结构】树与二叉树——二叉树的概念_数据结构_108

对不等式两边分别求解我们不难得到 【数据结构】树与二叉树——二叉树的概念_二叉树_109【数据结构】树与二叉树——二叉树的概念_二叉树_110

将该不等式改写成等式我们就得到了:

【数据结构】树与二叉树——二叉树的概念_C语言_97【数据结构】树与二叉树——二叉树的概念_数据结构_96。证明完毕。

对于二叉树的性质证明整体来说还是比较简单的,从整个证明的过程我们不难发现,这些性质都是基于树的性质进行的进一步推导,而对于完全二叉树的相关性质,我们借助图像的话能够更加容易的对其进行理解。因此在学习二叉树的过程中,建议大家遇到问题时,多画图,通过图像来帮助自己解决问题。

结语

今天的内容咱们就介绍到这里。在今天的内容中,我们知道了什么是二叉树,以及二叉树的一些基本性质,我们还认识了4种特殊的二叉树——满二叉树、完全二叉树、BST和AVL树。在接下来的内容中,我们同样会从数据结构的三要素出发进一步介绍二叉树这种数据结构,大家记得关注哦!!!

咱们今天的内容到这里就全部结束了,如果大家喜欢博主的内容,可以点赞、收藏加评论三连支持一下,当然也可以转发给身边需要的朋友。最后感谢各位的支持,咱们下一篇再见!!!