简单哈夫曼树的建立,及其编码、译码的详解和实现
基本术语
二叉树的带权路径长度
二叉树中所有叶子结点的带权路径长度之和
根到结点的路径长度
从根到结点的路径上的分支数
哈夫曼树二叉树
又称最优二叉树,是一带权路径长度最短的二叉树。
例:设结点a、b、c、d的权值分别为1、3、5、7,
二叉树(1)的带权路径长度=31+33+25+17=29
二叉树(2)的带权路径长度=21+23+25+27=32
二叉树(3)的带权路径长度=21+33+35+17=33
在所有可以构建的二叉树中,(1)的带权路径长度是最短,所以(1)是最优二叉树。
所以,那么问题来了。
怎么构建哈夫曼树呢?
构建哈夫曼树
算法
-
根据给定的n个权值{w1,w2,…,wn}构成n棵二叉树的集合F={T1,T2,…,Tn},其中每棵二叉树只含一个带权的根结点,其左右子树均空;
-
在F中选两棵根结点的权值最小的二叉树作为左右子树,构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和;
-
在F中删除这两棵二叉树,同时将新得到的二叉树加入F ;
-
重复2和3,直到F只含一棵二叉树,此即最优二叉树。
代码如下:
//HT为哈夫曼树,MIN为一结构体的命名。
for (int i = num + 1; i <= m; i++)
{
MIN min;
min=Select(HT,i-1);//选择并比较F中两权值最小的两个二叉树
HT[min.s1].parent = i;
HT[min.s2].parent = i;
HT[i].lchild = min.s1;//权值小的二叉树作为新生二叉树的左子树
HT[min.s1].num = "0";
HT[i].rchild = min.s2;//权值大的二叉树作为新生二叉树的右子树
HT[min.s2].num = "1";
HT[i].weight = HT[min.s1].weight + HT[min.s2].weight;//新生的二叉树权值为其左、右子树之和
HT[i].data = -1;
}
译码
输入一串字符,将他们用哈夫曼码的形式输出。
string estring;//创建一个字符串类型的数据,用于存储哈夫曼码
for(int i = 0;i <= s.size(); i++)
{
for(int x = 1; x <= m; x++)
{
if(hft[x].data == s[i])//将所选的字符与哈夫曼树中的字符进行对比
{
estring = estring + hft[x].num;//将哈夫曼码连接起来
x = m;
}
}
}
<