第5章 树和二叉树
本章中主要介绍下列内容:
1.树的定义和存储结构
2.二叉树的定义、性质、存储结构
3.二叉树的遍历、线索算法
4.树和二叉树的转换
5.哈夫曼树及其应用
课时分配:
1、2两个学时,3四个学时,4两个学时, 5两个学时,上机两个学时
重点、难点:
二叉树的遍历、线索算法、哈夫曼树及其应用
第一节 树
1.树的定义和基本运算
1.1 定义
树是一种常用的非线性结构。我们可以这样定义:树是n(n≥0)个结点的有限集合。若n=0,则称为空树;否则,有且仅有一个特定的结点被称为根,当n>1时,其余结点被分成m(m>0)个互不相交的子集T1,T2,...,Tm,每个子集又是一棵树。由此可以看出,树的定义是递归。
结点:数据元素的内容及其指向其子树根的分支统称为结点。
结点的度:结点的分支数。
终端结点(叶子):度为0的结点。
非终端结点:度不为0的结点。
结点的层次:树中根结点的层次为1,根结点子树的根为第2层,以此类推。
树的度:树中所有结点度的最大值。
树的深度:树中所有结点层次的最大值。
有序树、无序树:如果树中每棵子树从左向右的排列拥有一定的顺序,不得互换,则称为有序树,否则称为无序树。
森林:是m(m≥0)棵互不相交的树的集合。
在树结构中,结点之间的关系又可以用家族关系描述,定义如下:
孩子、双亲:结点子树的根称为这个结点的孩子,而这个结点又被称为孩子的双亲。
子孙:以某结点为根的子树中的所有结点都被称为是该结点的子孙。
祖先:从根结点到该结点路径上的所有结点。
兄弟:同一个双亲的孩子之间互为兄弟。
堂兄弟:双亲在同一层的结点互为堂兄弟。
1.2 树的基本运算
常用操作:
(1)构造一个树 CreateTree (T)
(2)清空以T为根的树 ClearTree(T)
(3)判断树是否为空 TreeEmpty(T)
(4)获取给定结点的第i个孩子 Child(T,linklist,i)
(5)获取给定结点的双亲 Parent(T,linklist)
(6)遍历树Traverse(T)
对树遍历的主要目的是将非线性结构通过遍历过程线性化,即获得一个线性序列。树的遍历顺序有两种,一种是先序遍历,即先访问根结点,然后再依次用同样的方法访问每棵子树;另一种是后序遍历,即先依
2. 树的存储结构
2.1 双亲表示法
类型定义:
#define MAX_TREE_LINKLIST_SIZE 100
typedef struct {
TElemtype info;
int parent;
} ParentLinklist;
typedef struct {
ParentLinklist elem[MAX_TREE_LINKLIST_SIZE];
int n; //树中当前的结点数目
}ParentTree;
这种存储方法的特点是寻找结点的双亲很容易,但寻找结点的孩子比较困难。
算法实现举例:
int Parent(ParentTree T,int linklist)
{ if (linklist<0||linklist>=T.n) return -2;
else return T.elem[linklist].parent;
}
2.2 孩子表示法
在C语言中,这种存储形式定义如下:
#define MAX_TREE_LINKLIST_SIZE 10
typedef struct ChildLinklist{
int child; //该孩子结点在一维数组中的下标值
struct ChileLinklist *next; //指向下一个孩子结点
}CLinklist;
typedef struct{
Elemtype info; //结点信息
CLinklist *firstchild; //指向第一个孩子结点的指针
}TLinklist;
typedef struct {
TLinklist elem[MAX_TREE_LINKLIST_SIZE];
int n,root; //n为树中当前结点的数目,root为根结点在一维数组中的位置
}ChildTree;
这种存储结构的特点是寻找某个结点的孩子比较容易,但寻找双亲比较麻烦,所以,在必要的时候,可以将双亲表示法和孩子表示法结合起来,即将一维数组元素增加一个表示双亲结点的域parent,用来指示结点的双亲在一维数组中的位置。
获取给定结点第i个孩子的操作算法实现:
int Child(ChildTree T, int linklist, int i)
{
if(linklist<0||linklist>=T.n) return -2;
p=T.elem[linklist].firstchild; j=1;
while (p&&j!=i) { p=p->next; j++;}
if(!p) return -2;
else return p->child;
}
2.3 孩子兄弟表示法
孩子兄弟表示法也是一种链式存储结构。它通过描述每个结点的一个孩子和兄弟信息来反映结点之间的层次关系,其结点结构为: