一.前言
本文主要介绍二叉树的一些定义和特性及存储
二叉树是树中一种特殊且重要的数据结构。二叉树种类繁多并且可以有很多变化,但究其本质:就是一个父节点有两个儿子;类似于链表,父节点保存数据,两个儿子结点分别指向下一个结点。
二. 二叉树的概念
1.二叉树的定义
:二叉树是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树组成。
如图,每一个结点中最多拥有一个左结点和一个右结点,并没有多余的结点,这是很明显的二叉树的特征
② 下面分别是二叉树的五种基本形态
(a)空 ----(b)独根 ----- ©空右 ------- (d)空左 --------- (e)左右都不空
2.几种特殊的二叉树
1.斜树:所有的结点都只有左子树的二叉树叫左斜树。所有结点都是只有右子树的二叉树叫右斜树。这两者统称为斜树。实际上已经退化为链表了
2.完美二叉树(满二叉树):在一棵二叉树中。如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。
满二叉树的特点有:
1)叶子只能出现在最下一层。出现在其它层就不可能达成平衡。
2)非叶子结点的度一定是2。
3)在同样深度的二叉树中,满二叉树的结点个数最多,叶子数最多。
3.完全二叉树(最下层最右边缺少结点的满二叉树):对一颗具有n个结点的二叉树按层编号,如果编号为i(1<=i<=n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。下图为完全二叉树
此图不为完全二叉树
3. 二叉树的特点
由二叉树定义以及图示分析得出二叉树有以下特点:
1)每个结点最多有两颗子树,所以二叉树中不存在度大于2的结点。
2)左子树和右子树是有顺序的,次序不能任意颠倒。
3)即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。譬如:
(1) 一个二叉树第 i 层的最大结点数为:2^(i-1),i >= 1。 (即完美二叉树的每层结点数)
(2) 深度为k的二叉树有最大结点总数为: 2^k-1,k>=1。(即完美二叉树的总结点数)
也可以理解为:包含n个结点的二叉树的高度至少为log2 (n+1)
(取一下对数即可证明。)
(3) 对任何非空二叉树 T,若n0表示叶结点的个数、n2是度为2的非叶结点个数,那么两者满足关系n0= n2+1。证明如下
三.二叉树的存储
1.链式存储
一颗二叉树的结点设计一定要有如下内容:
a)结点元素,data域,用来存储数据,其可以是int,char等基本的类型,同时也可以是struct等这些复杂的复合数据类型。
b)左孩子结点,left指针,总是用来指向当前结点的下一层的左边结点,其属于一种指针。
c)右孩子结点,right指针,总是用来指向当前结点的下一层的右边结点,其属于一种指针。
d)父结点(可选),parent指针,总是指向当前结点的前一个结点,简称父亲结点,其不属于必须结点设计,省略掉可以打扰节省内存的效果,而使用则可以更方便进行定向搜索,本案例中不使用父节点。
以上就是一颗二叉树的结点设计,除此之外,我们使用一棵树的时候需要建立一颗树根,由这个“根”,来进行逐步的向下构建。
其设计代码可以表示为:
链式图可这样表示
2.顺序存储
顺序存储多用于完成二叉树(比如构建一个heap),因为对于一般的二叉树这样存储会浪费很多空间。
①首先先对完全二叉树进行编号为了方便,让子节点的序号/2 (取左整)表示父节点的序号就可以表达各个结点的序号了;
例如:上述二叉树就可以在数组中这么表示:
**但是一般的二叉树使用顺序存储会浪费较多的空间,**比如:
定义这种顺序存储的二叉树(以heap代码为例),和栈的数据存储其实是类似的,只需要arr和size,capacity;