数据结构系列内容的学习目录 → \rightarrow →浙大版数据结构学习系列内容汇总。
2. 二叉树及存储结构
2.1 二叉树的定义
二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。
二叉树特点是每个结点最多只能有两棵子树,且有左右之分。
二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点 。
二叉树T: 一个有穷的结点集合。
⋄
\diamond
⋄ 这个集合可以为空。
⋄
\diamond
⋄ 若不为空,则它是由根结点和称为其左子树
T
L
T_{L}
TL和右子树
T
R
T_{R}
TR的两个不相交的二叉树组成。
二叉树具体五种基本形态:
二叉树的子树有左右顺序之分:
特殊二叉树:
- 斜二叉树(Skewed Binary Tree)
- 完美二叉树(Perfect Binary Tree)
满二叉树(Full Binary Tree)
- 完全二叉树(Complete Binary Tree)
有n个结点的二叉树,对树中结点按从上至下、从左到右顺序进行编号,编号为 i ( 1 ⩽ i ⩽ n ) i (1\leqslant i\leqslant n) i(1⩽i⩽n)的结点与满二叉树中编号为 i i i的结点在二叉树中的位置相同。
下图所示的二叉树不是完全二叉树,因为编号为4的结点的子结点只有一个,编号为9的结点与上图所示的二叉树中编号为9的结点位置不同。
2.2 二叉树几个重要性质
∙
\bullet
∙ 一个二叉树第
i
i
i层的最大结点数为:
2
i
−
1
2^{i-1}
2i−1,
i
≥
1
i≥1
i≥1。
∙
\bullet
∙ 深度为
k
k
k的二叉树有最大结点总数为:
2
k
−
1
2^{k}-1
2k−1,
k
>
1
k>1
k>1。
∙
\bullet
∙ 对任何非空二叉树T,若
n
0
n_{0}
n0表示叶结点的个数、
n
2
n_{2}
n2是度为2的非叶结点个数,那么两者满足关系
n
0
=
n
2
+
1
n_{0}= n_{2} +1
n0=n2+1。
上图所示的二叉树中,
n
0
=
4
n_{0}=4
n0=4,
n
1
=
2
n_{1}=2
n1=2,
n
2
=
3
n_{2}=3
n2=3,
n
0
=
n
2
+
1
=
4
n_{0}= n_{2} +1=4
n0=n2+1=4。
2.3 二叉树的抽象数据类型定义
类型名称: 二叉树
数据对象集: 一个有穷的结点集合
若不为空,则由根结点和其左、右二叉子树组成
操作集: BT
∈
∈
∈BinTree, Item
∈
∈
∈ElementType,重要操作有:
Boolean lsEmpty(BinTree BT)
:判别BT是否为空;void Traversal(BinTree BT)
:遍历,按某顺序访问每个结点;BinTree CreatBinTree()
:创建一个二叉树。
常用的遍历方法有:
void PreOrderTraversal(BinTree BT)
:先序 —— 根、左子树、右子树;void InOrderTraversal(BinTree BT)
:中序 —— 左子树、根、右子树;void PostOrderTraversal(BinTree BT)
:后序 —— 左子树、右子树、根;void LevelOrderTraversal(BinTree BT)
:层次遍历,从上到下、从左到右。
2.4 二叉树的存储结构
2.4.1 顺序存储结构
完全二叉树: 按从上至下、从左到右顺序存储
n个结点的完全二叉树的结点父子关系:
⋆
\star
⋆ 非根结点(序号
i
>
1
i >1
i>1)的父结点的序号是
i
/
2
i/2
i/2;
⋆
\star
⋆ 结点(序号为
i
i
i)的左孩子结点的序号是
2
i
2i
2i,若
2
i
⩽
n
2i\leqslant n
2i⩽n,则没有左孩子;
⋆
\star
⋆ 结点(序号为
i
i
i )的右孩子结点的序号是
2
i
+
1
2i+1
2i+1,若
2
i
+
1
⩽
n
2i+1\leqslant n
2i+1⩽n,则没有右孩子。
一般二叉树也可以采用如下图所示的这种结构,但会造成空间浪费。
2.4.2 链表存储结构
二叉树的链表存储数据结构定义如下所示。
typedef struct TreeNode *BinTree;
typedef BinTree Position; //二叉树类型
struct TreeNode{ //树结点定义
ElementType Data; //结点数据
BinTree Left; //指向左子树
BinTree Right; //指向右子树
}
如下图左边所示的二叉树,链表存储结构如右边所示。