数据结构初阶-树、二叉树的讲解

目录

1.树

1.1概念与结构

1.2树的相关术语

1.3树的表示

2.二叉树

2.1概念与结构

2.2特殊的二叉树

2.2.1满二叉树

2.2.2完全二叉树

2.3二叉树的存储结构

2.3.1顺序存储

2.3.2链式存储

3.总结


1.树

1.1概念与结构

树是一种非线性的数据结构(逻辑结构上一定不是线性的,物理结构上可能线性(取决于其底层结构,主要的还是非线性的))。因为其结构像一个倒挂的树所以称之为树,也就是说它的根朝上而叶朝下。树有以下几个特点:有一个特殊的结点称为根结点,根结点没有前驱结点;除根结点外其余的结点被分成很多个集合,每一个子树都有且仅有一个前驱结点,但是都有0个或多个后继结点。如下所示:

树形结构的特点:

子树之间不能有交集部分,比如,不能有F与G相连,这样就不是树形结构,而是图结构了。

1.2树的相关术语

通过上面两个图我们能知道树这个数据结构比较麻烦,所以我们通常是用递归来定义树的。

1.3树的表示

树的表示可以用双亲表示法,也可以用孩子表示法,孩子双亲表示法,孩子兄弟表示法等等。而最后一种为最常用的表示方法,所以我们简单介绍一下孩子兄弟表示法

struct TreeNode

{

struct Node* child;//左边最开始的第一个孩子结点

struct Node* brother;//指向其右边的下一个兄弟结点

int data;//结点中的数据域

};

如:

则这个二叉树的结构是这样:

2.二叉树

2.1概念与结构

特点:二叉树的度最多为2;二叉树有左右之分,次序不能颠倒,因此二叉树是有序树。

2.2特殊的二叉树

2.2.1满二叉树

如果一个二叉树每个层的结点数都达到最大值,即每一个父节点都存在两个子节点,或者都存在左右子树的情况(除了最后一层外),则这个二叉树又称为满二叉树。如果这个二叉树的层数为K,则第一层为1个结点,相当于2^0个结点,依次类推,最后一层为2^(k-1)个。相当于等比数列的求和,则结点总数为2^k-1,那么它就是满二叉树。如:

2.2.2完全二叉树

完全二叉树是由满二叉树所引申出来的一个特殊的二叉树。这个二叉树有以下特点:除最后一层外,其他层和满二叉树一样,如果这个二叉树的深度为K,则前K-1层每一个都有2^n,n从根结点开始为0,只有最后一层的结点数不多于2^(K-1)个,即没有排满,如:

2.3二叉树的存储结构

我们知道它的逻辑结构是我们想象出来的二叉树的样子,而物理结构还要看它的底层结构,二叉树可以用顺序结构来存储,也可以用链式结构存储。这两个存储有不同的代码,我之后都会讲。

2.3.1顺序存储

顾名思义,这个物理结构是线性的,是用数组来存储的。可是,二叉树的逻辑结构是非线性的,如何来存储呢?我们通过之前的学习知道数组存储需要知道大概这个数据的多少。如果我们直接用顺序存储来表示完全二叉树,因为这种二叉树它的结点总数最多为2^(k-1)个,浪费的空间较少,所以我们在之后会先讲这种特殊的,也是不需要考虑很多情况的二叉树,之后再讲其他类型的二叉树比较容易理解一些。而我们讲这种二叉树,通常顺序存储是来存储。这是一种特殊的二叉树。但是和我们在内存的地址空间中的堆不是一个概念,所以我们不能混淆。

那么,回归正题,顺序存储到底是怎么分配子节点和父节点的呢?如下图:

我们发现从根结点开始存储,其中根结点的下标为0,而后面从左往右进行存储数据。而非完全二叉树如果存储的话,会导致以下的情况:

这个二叉树的B结点没有左结点,我们不能跳过这个直接存储右(子)结点,而应当把这个位置空出来,类似,如果C结点没有子节点,则这个结点的子结点我们需要考虑把这个位置空着。但是这样产生了一个问题,如果不空出来的话会怎么样,这样我们就不用浪费空间去存储这个二叉树了啊?我们发现开始根结点与第一个子结点隔了一个位置,而如果B有左子结点的话,则隔了两个位置,而如果我们直接把右结点的数据存储到这个下标的位置,则就会导致本来B结点只有右子结点,而变为了有B的右结点和C的左结点了。所以这样存储找不到父子关系。所以我们需要另外一种存储结构是链式存储来避开这种情况。

2.3.2链式存储

这种存储模式有这个特点:是按照逻辑结构来存储数据的。所以我们可以通过这个链式结构来存储完全和非完全二叉树。但是我们应当如何来定义这种存储结构呢?有两种形式:二叉链表,三叉链表。

如图:

而我们在数据结构初阶只讲二叉链表,而在数据结构高阶将会讲解三叉链表。

3.总结

二叉树这种结构理解起来不是那么难,但是实现相对于之前的比较难,所以我们在学习的过程中要加以注意。下讲我将讲解堆的实现和应用。敬请期待吧!喜欢我的可以一键三连哦。