构造哈夫曼树,求哈夫曼编码的方法
第一步先构造哈夫曼树,然后再构造哈夫曼编码
1.构造哈夫曼树的方法:
算法:求哈夫曼树和哈夫曼表
void HuffmanCoding(Huffman Tree &HT,HuffmanCode &HC,int *w,int n)
{
//w存放n个字符的数组,构造哈夫曼树,求n个字符的哈夫曼编码表
if(n<=1)return;
m = 2*n-1;//n个字符的哈夫曼树有(2*n-1)个节点
HT=(HuffmanTree)malloc(m+1)*sizeof(HTNde);
for(p=HT,i=1;i<=n;++i,++P,++w) *p = {*w,0,0,0};//初始化,创建n个节点的二叉树,把n个节点赋权值
for(;i<=m;++i,++p) *p={0,0,0,0};//剩下的n-1个节点为0,i没有初始化。前边一个for循环结束i=n+1;接着上边的for循环
for(i=n+1;i<=n,++i){ //对n+1到m构造新的结点
select(HT,i-1,s1,s2);//选择parent为0且权值最小的两个结点,S1,S2;
HT[s1].parent = i;HT[s2].parent = i;//把S1S2的parent改变
HT[i] = s1;HT[i],child = s2; //左孩子和右孩子
HT[i].weight = HT[s1].weght + HT[s1].weight;// 权值之和
}
2.
有哈夫曼树求哈夫曼编码的方法
//一、从叶子结点到根逆向求每个字符的哈夫曼编码
算法:
//二、从根节点遍历哈夫曼树,求哈夫曼编码
算法;
3.例题;
例1:电文译码:分解电文中字符串,从根节点出发,按字符0/1确定左、右孩子,直到叶子节点
分析:假设电文为:101110110111
哈夫曼编码是一个不等长的
假设得到电文是如下表;
1 A 0 0
2 B 0 0
3 C 0 0
4 D 0 0
5 6 3 4
6 11 2 5
7 17 1 6
分析:分两种:从树中译码和从表格中译码
算法:j=1;i=1;
While(j<=code.len)
{
P=m;
while(p->lchild)||(p->rchild){
if code[j]=0 p=p-lchild
else p=p->rchild;
j=j+1;
}
}
例二:已知某系统在通信联络中只可能出现8种字符,其概率分布为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11
试设计哈夫曼编码。
首先设8个字符的权分别为w={5,29,7,8,14,23,3,11}
n=8,则m=15,即在有8个叶子结点的哈夫曼树上有15个结点,然后构造一颗哈夫曼树
最后就得到哈夫曼树,余下部分见例二图
P:相等先取叶子结点,新造的结点在右边,原来的结点在左边