文章目录
二叉树(Binary Tree)
-
定义:二叉树是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的分别称作这个根的左子树和右子树的二叉树组成。
-
特点:
① 每个结点最多有俩孩子(二叉树中不存在度大于2的结点)。
② 子树有左右之分,其次序不能颠倒。
③ 二叉树可以是空集合,根可以有空的左子树或空的右子树。 -
注意:
① 二叉树不是树的特殊情况,它们是两个概念。
② 二叉树结点的子树要区分左子树和右子树,即使只有一棵子树也要进行区分,说明它是左子树,还是右子树。
③ 树当结点只有一个孩子时, 就无须区分它是左还是右的次序。因此二者是不同的。这是二叉树与树的最主要的差别。
④ 也就是二叉树每个结点位置或者说次序都是固定的,可以是空,但是不可以说它没有位置,而树的结点位置是相对于别的结点来说的,没有别的结点时,它就无所谓左右了。 -
二叉树的基本形态
二叉树的性质
- 在二叉树的第i层上至多有2i-1个结点(i≥1),至少有1个结点。
- 深度为k的二叉树至多有2k- 1个结点(k≥1),至少有k个结点。
- 对任何一棵叉树T,如果其叶子数为 n0,度为2的结点数为n2,则n0= n2+ 1。
二叉树的抽象数据类型定义
ADT BinaryTree{
数据对象D:D是具有相同特性的数据元素的集合。
数据关系R:若D=∅,则R=∅;
若D≠∅,则R={H};H是如下二元关系:
① root唯一//关于根的说明
② D(j)∩D(k)=∅//关于子树不相交的说明
③ ......//关于数据元素的说明
④ ......//关于左子树和右子树的说明
基本操作P:CreateBiTree(&T,definition)
初始条件:definition给出二叉树T的定义。
操作结果:按definition构造二叉树T。
PreQrderTraverse(T)
初始条件:二叉树T存在。
操作结果:先序遍历T,对每个结点访问一次。
InOrderTraverse(T)
初始条件:二叉树T存在。
操作结果:中序遍历T,对每个结点访问一次。
PostQrderTraverse(T)
初始条件:二叉树T存在。
操作结果:后序遍历T,对每个结点访问一次。
}ADT BinaryTree
特殊形式的二叉树
满二叉树(Full Binary Tree)
- 定义:一棵深度为k且有2k- 1个结点的二叉树称为满二叉树。
- 特点:
① 每一层上的结点数都是最大结点数(即每层都满)。
② 叶子节点全部在最底层。
③ 所有的支结点都有左、右子树。
④ 只有度为0和度为2的结点,叶子结点都在最下一层。除最后一层外,其他各层上的每个结点的度都为2。
⑤ 空二叉树及只有根结点的二叉树也是满二叉树。
⑥ 对满二叉树结点位置进行编号规则:从根结点开始,自上而下,自左而右。每一结点位置都有元素。
满二叉树在同样深度的二叉树中结点个数最多;
满二叉树在同样深度的二叉树中叶子结点个数最多。
完全二叉树(Complete Binary Tree)
- 定义:深度为k的具有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号为1~ n的结点一对应时,称之为完全二叉树。
tips:在满二叉树中, 从最后一个结点开始,连续去掉任意个结点,即是一棵完全二叉树。
- 特点:
① 叶子只可能分布在层次最大的两层上。
② 对任一结点, 如果其右子树的最大层次为i,则其左子树的最大层次必为i或i+1。
完全二叉树是满二叉树的一部分,而满二叉树是完全二叉树的特例。
完全二叉树不一定是满二叉树,满二叉树一定是完全二叉树。
-
性质:
① 表明了完全二叉树结点数n与完全二叉树深度k之间的关系:
② 表明了完全二叉树中双亲结点编号与孩子结点编号之间的关系:
二叉树的存储结构
二叉树的顺序存储结构
- 实现:按满二叉树的结点层次编号,依次存放二叉树中的数据元素。
- 顺序存储结构定义:
//二叉树顺序存储表示
#define MAXTSIZE 100
Typedef TElemType SqBiTree[MAXTSIZE]
SqBiTree bt;
- 二叉树的顺序存储缺点:
结点间关系蕴含在其存储位置中浪费空间,适于存满二叉树和完全二叉树。
最坏情况:深度为k的且只有k个结点的单支树需要长度为2k-1的一维数组。
二叉树的链式存储结构
- 二叉树结点的特点:
- 链式存储结点结构:
- 链式存储结构定义:
typedef struct BiNode{
TElemType data;
struct BiNode *lchild,*rchild;//左右孩子指针
}BiNode,*BiTree;
- 链式存储结构:
例:
- 三叉链表