树
树结构的基本术语
- 结点拥有的子树数称为结点的度
- 度为0的结点称为叶子或终端结点
- 度不为0的结点称为非终端结点或分支节点
- 树的度是指树内各结点的度的最大值
- 结点的祖先是从根到该结点所经分支上的所有结点
- 结点的层次从根开始定义起,根为第一层,树中结点的最大层次称为树的深度或者高度
- 如果将树中结点的各子树看出从左到右是有次序的,则称该树为有序树,否则称为无序树。在有序树中最左边的子树的根称为第一个孩子,最右边的称为最后一个孩子。
- 森林是m棵互不相交的树的集合,对树中每一个结点来说,其子树的集合即为森林。
二叉树
二叉树的定义
二叉树的特点是每个结点至多只有两棵子树,并且二叉树的子树有左右之分,其次序不能任意颠倒。
二叉树的基本操作
InitBiTree(&T)
操作结果:构造空二叉树T
DestroyBiTree(&T)
操作结果:销毁二叉树T
CreateBiTree(&T,definition)
初始条件:definition给出二叉树的T的定义
操作结果:按difinition构造二叉树T
ClearBiTree(&T)
操作结果:将二叉树T清为空树
BiTreeEmpty(T)
操作结果:若T为空二叉树,则返回TRUE,否则FALSE
BiTreeDepth(T)
操作结果:返回T的深度
Root(T)
操作结果:返回T的根
Value(T,e)
初始条件:e是T中某个结点
操作结果:返回e的值
Assign(T,&e,value)
初始条件:二叉树T存在,e是T中某个结点
操作结果:结点e赋值为value
Parent(T,e)
操作结果:若e是T的非根结点,则返回它的双亲,否则返回“空”
LeftChild(T,e)
操作结果:返回e的左孩子,若e无左孩子,则返回“空”
RightChile(T,e)
操作结果:返回e的右孩子,若e无右孩子,则返回“空”
LeftSibling(T,e)
操作结果:返回e的左兄弟,若没有左兄弟,则返回“空”
RightSibling(T,e)
操作结果:返回e的右兄弟,若没有右兄弟,则返回“空”
InsertChild(T,p,LR,c)
初始条件:二叉树T存在,p指向T中某一个结点,LR为0或1,非空二叉树c与T不相交且右子树为空
操作结果:根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点的原有左或右子树则成为c的右子树
DeleteChild(T,p,LR)
初始条件:二叉树T存在,p指向T中某一个结点,LR为0或1
操作结果:根据LR为0或1,删除T中p所指结点的左或右子树
PreOrderTraverse(T,Visit())
初始条件:二叉树T存在,Visit是对结点操作的应用函数
操作结果:先序遍历T,对每个结点调用函数Visit一次且仅一次。一旦visit()失败,则操作失败
InOrderTraverse(T,Visit())
中序遍历
PostOrderTraverse(T,Visit())
后序遍历
LevelOrderTraverse(T,Visit())
层序遍历
二叉树的性质
- 在二叉树的第i层上最多有 2 i − 1 2^{i-1} 2i−1个结点
- 深度为k的二叉树至多有 2 k − 1 2^{k}-1 2k−1个结点(用性质1等比求和)
- 对任何一颗二叉树T,如果其终端结点数为 n 0 n_0 n0,度为2的结点数为 n 2 n_2 n2,则 n 0 n_0 n0= n 2 n_2 n2+1
- 一颗深度为k且有 2 k − 1 2^{k}-1 2k−1个结点的二叉树成为满二叉树,也就是每一层上的结点数都是最大结点数。
- 若结点的分布为从左往右进行排序的,不跳跃,那就是完全二叉树
- 具有n个节点的完全二叉树的深度为 ⌊ l o g 2 n ⌋ + 1 \lfloor log_2n \rfloor+1 ⌊log2n⌋+1
二叉树的存储结构
顺序存储结构
#define MAX_TREE_SIZE 100 //二叉树的最大结点数
typedef TElemType SqBiTree[MAX_TREE_SIZE];
SqBiTree bt;
按照顺序存储结构的定义,在此约定,用一组地址连续的存储单元依次自上而下,自左至右存储完全二叉树上的结点元素,即将完全二叉树上编号为i的结点元素存储在如上定义的一维数组中下标为i-1的分量中。对于一般二叉树在,则应将其每个结点与完全二叉树上的结点相对照,存储在一维数组的对应分量中,若不存在某一号完全二叉树对应的结点,就用“0”表示不存在此结点。由此看来,这种顺序存储结构只适用于完全二叉树。