知识大全 树 - 哈夫曼树及其应用 - 最优二叉树(二)
Posted 结点
篇首语:一箫一剑平生意,负尽狂名十五年。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 树 - 哈夫曼树及其应用 - 最优二叉树(二)相关的知识,希望对你有一定的参考价值。
构造最优二叉树
哈夫曼算法
哈夫曼首先给出了对于给定的叶子数目及其权值构造最优二叉树的方法 故称其为哈夫曼算法 其基本思想是
( )根据给定的n个权值w l w … w n 构成n棵二叉树的森林F=T T … T n 其中每棵二叉树T i 中都
只有一个权值为w i 的根结点 其左右子树均空
( )在森林F中选出两棵根结点权值最小的树(当这样的树不止两棵树时 可以从中任选两棵) 将这两棵树合并成一棵新树 为
了保证新树仍是二叉树 需要增加一个新结点作为新树的根 并将所选的两棵树的根分别作为新根的左右孩子(谁左 谁右无关紧要
) 将这两个孩子的权值之和作为新树根的权值
( )对新的森林F重复( ) 直到森林F中只剩下一棵树为止 这棵树便是哈夫曼树
用哈夫曼算法构造哈夫曼树的过程见【 动画演示 】
注意
① 初始森林中的n棵二叉树 每棵树有一个孤立的结点 它们既是根 又是叶子
② n个叶子的哈夫曼树要经过n 次合并 产生n 个新结点 最终求得的哈夫曼树中共有 n 个结点
③ 哈夫曼树是严格的二叉树 没有度数为 的分支结点
哈夫曼树的存储结构及哈夫曼算法的实现
( ) 哈夫曼树的存储结构
用一个大小为 n 的向量来存储哈夫曼树中的结点 其存储结构为
#define n //叶子数目
#define m *n //树中结点总数
typedef struct //结点类型
float weight; //权值 不妨设权值均大于零
int lchild rchild parent; //左右孩子及双亲指针
HTNode;
typedef HTNode HuffmanTree[m]; //HuffmanTree是向量类型
注意
因为C语言数组的下界为 故用 表示空指针 树中某结点的lchild rchild和parent不等于 时 它们分别是该结点的左
右孩子和双亲结点在向量中的下标
这里设置parent域有两个作用 其一是使查找某结点的双亲变得简单;其二是可通过判定parent的值是否为 来区分根与非根结
点
( )哈夫曼算法的简要描述
在上述存储结构上实现的哈夫曼算法可大致描述为(设T的类型为HuffmanTree)
( )初始化
将T[ m ]中 n 个结点里的三个指针均置为空(即置为 ) 权值置为
( )输人
读人n个叶子的权值存于向量的前n个分量(即T[ n ])中 它们是初始森林中n个孤立的根结点上的权值
( )合并
对森林中的树共进行n 次合并 所产生的新结点依次放人向量T的第i个分量中(n≤i≤m ) 每次合并分两步
①在当前森林T[ i ]的所有结点中 选取权最小和次小的两个根结点[p ]和T[p ]作为合并对象 这里 ≤p p ≤i
② 将根为T[p ]和T[p ]的两棵树作为左右子树合并为一棵新的树 新树的根是新结点T[i] 具体操作
将T[p ]和T[p ]的parent置为i
将T[i]的lchild和rchild分别置为p 和p
新结点T[i]的权值置为T[p ]和T[p ]的权值之和
注意
合并后T[pl]和T[p ]在当前森林中已不再是根 因为它们的双亲指针均已指向了T[i] 所以下一次合并时不会被选中为合并对象
哈夫曼算法模拟演示过程【 参见动画模拟 】
( )哈夫曼算法的求精
void CreateHuffmanTree(HuffmanTree T)
//构造哈夫曼树 T[m ]为其根结点
int i p p ;
InitHuffmanTree(T); //将T初始化
InputWeight(T); //输入叶子权值至T[ n ]的weight域
for(i=n;i
SelectMin(T,i-1,&p1,&p2);
//在T[0..i-1]中选择两个权最小的根结点,其序号分别为p1和p2
T[p1].parent=T[p2].parent=i;
TIi].1child=p1; //最小权的根结点是新结点的左孩子
T[j].rchild=p2; //次小权的根结点是新结点的右孩子
T[i].weight=T[p1].weight+T[p2].weight;
// end for
上述算法中调用的三个函数【参见练习】。winGwit
【例】以7个权值:7,5,1,4,8,10,20为例,执行CreateHuffmanTree求最优二叉树的过程
cha138/Article/program/sjjg/201311/23864相关参考