哈夫曼编码的特点:
因为哈夫曼树的特点是:叶子结点权值越大的,离根越近。又因为构造不等长编码的原则是:字符使用频率越高,编码越短,故采用哈夫曼树进行编码可以得到最优前缀编码。
约定左分支标记为0, 右分支标记为 1
求哈夫曼编码:
为不浪费存储空间,动态分配一个长度为n(字符编码长度一定小于n) 的一维数组cd, 用来临时存放当前正在求解的第i个字符的编码,当第i个字符的编码求解完毕后,根据数组cd的字符串长度分配HC[i]的空间,然后将数组cd中的编码复制到HC[i]中。
依照上一篇文章的哈夫曼树:
哈夫曼编码表HC:
注意:由于哈夫曼树不唯一,故哈夫曼编码也不唯一。
代码如下:
#include<stdio.h>
#include<iostream>
//哈夫曼树定义
typedef struct {
int weight;
int parent, lchild, rchild;
}HTNode, *HuffmanTree;
//选择两个双亲域为0且权值最小的结点,并返回在HT中的序号s1,s2
void Select(HuffmanTree &HT, int n, int &s1, int &s2)
{
//寻找第一个双亲域为0且权值最小的结点
int min;
for (int i = 1; i <= n; i++) //找到第一个双亲域为0的,下标暂存到min
{
if (HT[i].parent == 0)
{
min = i;
break;
}
}
for (int i = 1; i <= n; i++)
{
if (HT[i].parent == 0)
{
if (HT[i].weight < HT[min].weight)
{
min = i;
}
}
}
s1 = min;
//寻找第二个双亲域为0且权值最小的结点
for (int i = 1;