学习笔记:树和二叉树的初步学习2

三、树和森林

1、树的存储结构

常用的链表结构:

a.双亲表示法

以一组连续空间存储树的结点,同时,结点结构中附设一个指示其双亲结点在链表中的位置的指示器。

#define MAX_TREE_SIZE 50
typedef struct PTNode{
TElemType data;
int parent;  //双亲位置
}PTNode; 
typedef struct{
PTNode nodes[MAX_TREE_SIZE];
int r,n;   //根的位置和结点数
}PTree;

这种存储结构利用了除根结点以外的每个结点只有一个双亲的性质,Parent(T,x)函数可找到其双亲。反复调用Parent函数,直到遇到无双亲的结点时,便找到了树的根。

在这种表示法中,求结点的孩子时很不方便。

2、孩子表示法

这种表示方法是把每个结点的孩子结点排列起来,看成是一个线性表,每个孩子结点以单链表作为存储结构,则n个结点有n个孩子链表(叶子结点的孩子链表为空表)。而n个头指针又组成一个线性表,为了便于查找,采用顺序存储结构。

typedef struct CTNode{  //孩子结点
int child;
struct CTNode *next;
}*ChildPtr;
typedef struct{  
TElemType data;
ChildPtr firstchild;   //孩子链表头指针
}CTBox;
typedef struct{
CTBox nodes[MAX_TREE_SIZE];
int n,r;   //结点数和根的位置
}CTree;

这种表示法便于实现关于结点孩子的操作。

可以把双亲表示法和孩子链表结合起来,可以实现关于两头的操作。


c.孩子兄弟表示法

此又称为二叉链表表示法。链表中每个节点有两个链域,分别指向该结点的第一个孩子结点和下一个兄弟结点。

这样,将树转化为二叉树,以二叉链表形式存储。

typedef struct CSNode{
ElemType data;
struct CSNode *firstchild,*nextsibling;  //两个链域
}CSNode,*CSTree;

给定一棵树,可以找到唯一的一棵二叉树与之对应。从物理结构方面,它们的二叉链表是相同的,只是域的名称不同、解释不同而已。

任何一颗和树对应的二叉树,其右子树必空。


2.森林与二叉树的转换

按照树与二叉树的对应关系,将森林中第二棵树的根结点看成是第一棵树的根结点的兄弟,那么,森林也可转化为二叉树。

这时的二叉树有右子树。

森林和树的操作可转换为二叉树的操作。


3.树和森林的遍历

两种遍历树的方法:

一种是先根(次序)遍历树。即先访问树的根结点,然后依次先根遍历根的每棵子树。

另一种是后根(次序)遍历,即先依次后根遍历每棵子树,再访问根结点。


森林由三部分组成:①第一棵树的根节点;②第一棵树的子树森林;③除第一棵树以外的其他树构成的森林。

按照森林和树相互递归的定义,可推出森林的两种遍历方法:先序遍历和中序遍历。


遍历对应关系:

树的先根遍历<——>二叉树先序遍历<——>森林先序遍历

树的后根遍历<——>二叉树中序遍历<——>森林中序遍历

注意:森林的中序遍历指依次从左至右对森林中每棵树进行后根遍历。


借用二叉树的先序和中序遍历算法可实现遍历树和森林。因此二叉树的遍历是很重要的。


四、赫夫曼树

赫夫曼树又称最优树,是一类带权路径长度最短的树。

1、最优二叉树

路径上的分支数目称为路径长度。

树的路径长度:从树根到每一结点的路径长度之和。

树的带权路径长度:树中所有叶子结点的带权路径长度之和。

带权路径长度最小的二叉树称作最优二叉树或赫夫曼树。

2、赫夫曼编码

进行快速远距离通信时,将需传送的文字转换成由二进制的字符组成的字符串,并且总长尽可能短,以提高传送效率。

可以对每个字符设计长短不同的编码,让电文中出现次数角度的字符采用尽可能短的编码,则电文总长可大大减少。

要设计长短不等的编码,必须是任一个字符的编码都不是另一个字符的编码的前缀,这种编码称作前缀编码。

设计电文总长最短的二进制前缀编码,即为设计一颗赫夫曼树的问题,权值为n种字符出现的频率。每条路径形成的编码为赫夫曼编码。


总结:二叉树的遍历是重中之重。学会树和森林与二叉树的转换。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值