目录
一、哈夫曼树的定义
二、哈夫曼树的特点
三、哈夫曼算法(构造哈夫曼树的方法)
四、哈夫曼树的构造过程
五、哈夫曼树构造算法的实现
1、哈夫曼树:最优树即带权路径长度(WPL)最短的树
“带权路径长度最短”是在"度相同”的树中比较而得的结果,因此有最优二叉树、最优三叉树之称等等。
2、哈夫曼树:最优二叉树即带权路径长度(WPL)最短的二叉树
因为构造这种树的算法是由哈夫曼教授于1952年提出的,所以被称为哈夫曼树,相应的算法称为哈夫曼算法。
1、满二叉树不一定是哈夫曼树
2、哈夫曼树中权越大的叶子离根越近
3、具有相同带权结点的哈夫曼树不唯一
1、算法步骤
(1)根据n个给定的权值{W1, W2,...,Wn}构成n棵二叉树的森林,F={T1, T2,...,Tn},其中Ti只有一个带权为Wi的根结点。
构造森林全是根
(2)在F中选取两棵根结点的权值最小的树作为左右子树,构造一棵新的二叉树,且设置新的二又树的根结点的权值为其左右子树上根结点的权值之和。
选用两小造新树
(3)在F中删除这两棵树,同时将新得到的二叉树加入森林中,
删除两小添新人
(4)重复(2)和(3),直到森林中只有一棵树为止,这棵树即为哈夫曼树。
重复2、3剩单根
2、哈夫曼算法口诀:①构造森林全是根;②选用两小造新树;③删除两小添新人;④重复2、3剩单根。
如下图所示
由上图的过程可得出以下三个结论:
①包含n棵树的森林要经过n-1次合并才能形成哈夫曼树,共产生n-1 个新结点。
②包含n个叶子结点的哈夫曼树中共有2n- 1个结点。
③经过n-1次合并产生n-1个新结点,且这n-1个新结点都是具有两个孩子的分支结点。
④哈夫曼树的结点的度数为0或2,没有度为1的结点。
1、顺序存储结构的节点类型以及存储结构图如下图所示
2、算法思路
3、算法描述
void CreatHuffmanTree (HuffmanTree HT, int n){ //构造哈夫曼树——哈夫曼算法
if(n<= 1) return;
m=2*n-1; //数组共2n-1个元素
HT= new HTNode[m+1]; //0号单元未用,HT[m]表示根结点
for(i=1;i<=m;++i){ //将2n-1个元素的lch、 rch、 parent置为0
HT[i].lch=0; HT[i].rch=0; HT[i].parent=0;
}
for(i=1;i<=n;++i)
cin>>HT[i].weight; //输入前n个元素的weight值
//初始化结束,下面开始建立哈夫曼树
for(i=n+1;i<=m;i++){//合并产生n-1个结点——构造Huffman树
Select(HT, i-1, s1, s2); //在HT[k](1≤k≤i-1)中选择两个其双亲域为0,
//且权值最小的结点并返回它们在HT中的序号s1和s2
HT[s1].parent=i; HT[s2].parent=i; //表示从F中删除s1,s2
HT[i].lch=s1; HT[i].rch=s2; //s1,s2分别作为的左右孩子
HT[i].weight=HT[s1].weight + HT[s2].weight; //i的权值为左右孩子权值之和
}
}