【知识框架】
5.1 树的基本概念
5.1.1 树的定义
树是n(n≥0)个结点的有限集。当n=0时,称为空树。在任意一棵非空树中应满足:
- 有且仅有一个特定的称为根的结点。
- 当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,⋯,Tm,其中每个集 合本身又是一棵树,并且称为根的子树。
5.1.2 基本术语
下面结合图5.1 中的树来说明一些基本术语和概念。
1、祖先、子孙、双亲、孩子、兄弟和堂兄弟。
考虑结点 K,从根A到结点K的唯一路径上的所有其他结点,称为结点K的祖先。如结 点B是结点K的祖先,而K是B的子孙,结点B的子孙包括E,F,K,L。路径上最接近 结点K的结点E称为K的双亲,而K为E的孩子。根A是树中唯一没有双亲的结点。有 相同双亲的结点称为兄弟,如结点K和结点L有相同的双亲 E,即K和L为兄弟。双亲 在同一层的结点互为堂兄弟,结点G与E,F,H,I,J互为堂兄弟。
2、结点的度和树的度。
树中一个结点的孩子个数称为该结点的度,树中结点的最大度数称为树的度。如结点 B 的度为 2,结点D的度为3,树的度为3。
3、分支结点和叶结点。
度大于0的结点称为分支结点(又称非终端结点);度为0(没有孩子结点)的结点称为 叶结点(又称终端结点)。在分支结点中,每个结点的分支数就是该结点的度。
4、结点的深度、高度和层次。
结点的层次从树根开始定义,根结点为第1层,它的孩子为第2层,以此类推。结点的 深度就是结点所在的层次。树的高度(或深度)是树中结点的最大层数。结点的高度是 以该结点为根的子树的高度。图 5.1 中树的高度为4。
5、有序树和无序树。
树中结点的各子树从左到右是有次序的,不能互换,称该树为有序树,否则称为无序树。假设图5.1为有序树,若将子结点位置互换,则变成一棵不同的树。
6、路径和路径长度。
树中两个结点之间的路径是由这两个结点之间所经过的结点序列构成的,而路径长度是路径上所经过的边的个数。
7、森林。
森林是m(m≥0)棵互不相交的树的集合。森林的概念与树的概念十分相近,因为只要 把树的根结点删去就成了森林。反之,只要给m棵独立的树加上一个结点,并把这m棵 树作为该结点的子树,则森林就变成了树。
5.1.3 树的性质
- 树的结点数n等于所有结点的度数之和加1。
- 度为m的树中第i层上至多有mi-1个结点(i≥1)。
- 高度为h的m叉树至多有(mh-1)/(m-1)个结点。
- 度为m、具有n个结点的树的最小高度h为「logm(n(m-1)+1)]。
- 度为m、具有n个结点的树的最大高度h为n-m+1。
5.2 二叉树的概念
5.2.1 二叉树的定义及其主要特性
1. 二叉树的定义
二叉树是一种特殊的树形结构,其特点是每个结点至多只有两棵子树(即二叉树中不存在度 大于2的结点),并且二叉树的子树有左右之分,其次序不能任意颠倒。
二叉树与度为2的有序树的区别:
- 度为2的树至少有3个结点,而二叉树可以为空。
- 度为 2的有序树的孩子的左右次序是相对于另一个孩子而言的,若某个结点只有一个孩 子,则这个孩子就无须区分其左右次序,而二叉树无论其孩子数是否为2,均需确定其左 右次序,即二叉树的结点次序不是相对于另一结点而言的,而是确定的。
2. 几种特殊的二叉树
满二叉树
一棵高度为 h,且有2*-1个结点的二叉树称为满二叉树。
完全二叉树
高度为 h、有n个结点的二叉树,当且仅当其每个结点都与高度为 h的 满二叉树中编号为1~n的结点一一对应时,称为完全二又树,如图5.3(b)所示。其特 点如下:
- 若i≤[n/2](向下取整),则结点i为分支结点,否则为叶结点。
- 叶结点只可能在层次最大的两层上出现。对于最大层次中的叶结点,都依次排列在该 层最左边的位置上。
- 若有度为1的结点,则最多只可能有一个,且该结点只有左孩子而无右孩子。
- 按层序编号后,一旦出现某结点(编号为 i)为叶结点或只有左孩子,则编号大于i 的结点均为叶结点。
- 若n为奇数,则每个分支结点都有左孩子和右孩子;若n为偶数,则编号最大的分支 结点(编号为n/2)只有左孩子,没有右孩子,其余分支结点左、右孩子都有。
二叉排序树
左子树上所有结点的关键字均小于根结点的关键字;右子树上所有结点的 关键字均大于根结点的关键字;左子树和右子树又各是一棵二叉排序树。
平衡二叉树
树中任意一个结点的左子树和右子树的高度之差的绝对值不超过1。
3. 二叉树的性质
- 非空二叉树上的叶结点数等于度为2的结点数加1,即n0=n2+1。
- 非空二叉树的第k层最多有2(k-1)次方个节点
- 高度为h的二叉树至多有2h次方-1个节点
5.2.2 二叉树的存储结构
1. 顺序存储结构
2. 链式存储结构
由于顺序存储的空间利用率较低,因此二叉树一般都采用链式存储结构,用链表结点来存储 二叉树中的每个结点。在二叉树中,结点结构通常包括若干数据域和若干指针域,二叉链表至少 包含3个域:数据域data、左指针域lchild和右指针域rchild,如图5.5所示。
二叉树的链式存储结构描述如下:
cpp
typedef struct BiTNode {
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;