大家好,今天给大家介绍一下数据结构中二叉树的相关概念,一起来看看吧!
1.树的概念
1.1树的概念结构
树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。它看起来像一棵倒挂的树,根朝上,而叶朝下的。


- 有一个特殊的结点,根结点。除了根结点外,每个结点有且仅有一个父结点。
- 其余结点被分成n个互不相交的集合,每个集合又是一个结构与树类似的子树。
- 因此,树是递归定义的。
1.2树的相关概念

着重了解:结点的度,树的度,父结点,子结点,根结点,叶结点
结点的度:一个结点含有的子树的个数称为该结点的度; 如上图:A的为6
叶结点或终端结点:度为0的结点称为叶结点; 如上图:B、C、H、I…等结点为叶结点
非终端结点或分支结点:度不为0的结点; 如上图:D、E、F、G…等结点为分支结点
双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点; 如上图:A是B的父结点
孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点; 如上图:B是A的孩子结点
兄弟结点:具有相同父结点的结点互称为兄弟结点; 如上图:B、C是兄弟结点
树的度:一棵树中,最大的结点的度称为树的度; 如上图:树的度为6
结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推;
树的高度或深度:树中结点的最大层次; 如上图:树的高度为4
堂兄弟结点:双亲在同一层的结点互为堂兄弟;如上图:H、I互为兄弟结点
结点的祖先:从根到该结点所经分支上的所有结点;如上图:A是所有结点的祖先
子孙:以某结点为根的子树中任一结点都称为该结点的子孙。如上图:所有结点都是A的子孙
森林:由m(m>0)棵互不相交的树的集合称为森林;
2.树的表示
实际中树有很多种表示方式如:双亲表示法,孩子表示法、孩子双亲表示法以及孩子兄弟表示法等。我们这里就简单的了解其中最常用的孩子兄弟表示法。
后续四种树的表示方法,会在后续博客更新,想了解的朋友蹲一下吧~
这里我们主要介绍二叉树的具体实现
2.1孩子兄弟表示法

含义:任何一棵树,它的结点的第一个孩子如果是唯一的,它的右兄弟如果存在也是唯一的,因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟。


- data是数据域
- firstchild是孩子域
- rightsib是右兄弟域
具体关系图如下:

2.2双亲表示法
简单介绍,就是每个结点除了直到自己是谁外,还要直到自己的双亲在哪里。因此,它需要有数据域data和双亲域parent。

由于跟结点没有双亲,所以我们约定根结点的位置域设置为-1


3.二叉树
3.1概念
一棵二叉树是结点的一个有限集合,该集合:
- 或者为空
- 由一个根结点加上两棵别称为左子树和右子树的二叉树组成
- 二叉树不存在度大于2的结点
- 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树



3.2特殊的二叉树
- 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。如果一个二叉树的层数为k,且总结点数为2^k-1,它就是满二叉树。
- 完全二叉树:由满二叉树引出来, 完全二叉树是效率很高的数据结构。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

满二叉树比较好认,这里不多赘述。

完全二叉树:最后一层不满,但从左到右必须是连续的。
例如,下面这图就不符合完全二叉树,因为最后一层从左到右没有连续。

3.3二叉树的性质
默认初始状态:若规定根结点的层数是1
1.则一棵非空二叉树的第i层上最多有2^(i-1)个结点
2.深度为h的二叉树的最大结点数是2^h-1
3.任意一棵二叉树,如果度为0其叶结点个数为n0,度为2其叶结点个数为n2,则有n0=n2+1

了解一下即可……
3.4二叉树的存储结构
二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。
- 顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺序存储在逻辑结构上是一棵二叉树,在物理是一个数组。
- 链式存储:用链表来表示一棵二叉树。链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址
数组存储只适合完全二叉树:


4.二叉树的顺序结构和实现
4.1二叉树的顺序结构
上述讲到,二叉树可用两种结构存储,顺序存储结构和链式结构。
顺序结构就是用数组来存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。

4.1堆的概念和结构
把一个集合 按 完全二叉树 的 顺序结构存储 存放在一个数组中,并符合某些数学特点,由此把堆分为大堆和小堆。
大堆:根结点最大的堆
小堆:根结点最小的堆

4.2堆的特点
- 某个结点的值总是大于或者小于父结点的值‘
- 堆是一棵完全二叉树
5.堆的实现
5.1堆的初始化及销毁
堆的结构体定义,堆的初始化和堆的销毁,想必大家已经轻车熟路,咱们这里直接给出:


5.2堆的插入
完全二叉树, 顺序结构存储,数组 ;
实现思路:
- 先将元素插到堆的末尾,即最后一个孩子之后;
- 插入之后如果的堆的性质遭到破坏,将新插入结点顺着其双亲向上调整到合适位置即可。
注意:
- 堆的插入跟顺序表的差不多,因为都以数组为基础。
- 插入元素前,要判断内存是否足够,不够要扩容。

但是写到这里只是插入了一个数据,而堆是有某种特定结构的,因此我们得调整一下新数组中各个元素的位置。这里:向上调整


到这里,一共两步,堆的插入才完成~

调试结果1:


纠错:堆的插入,最后部分应为:php->a[php->size]=x而不是size-1

1万+

被折叠的 条评论
为什么被折叠?



