哈夫曼编码是一种被广泛应用而且非常有效的无损数据压缩技术,它是一种特殊类型的前缀编码,并且是变长编码方式。哈夫曼编码是David A.Huffman在读博士时开发的算法。作为麻省理工学院的学生,他于1952年发表题为“构建最小冗余码的方法”的论文。尽管哈夫曼编码这几个字不常出现在我们的日常生活中,但是它与L7ZZ共同组成的DEFLATEE压缩算法被zip压缩文件所使用,而zip压缩文件在生活中的许多地方起到了非常重要的作用。无论是Mac OS,Unix还是Windows系统都对zip压缩文件有原生的支持。数据包在网络中的传输便使用了zip压缩算法。当今使用广泛的PNG,JPEG,WebP图像格式,所使用的压缩算法也包含了哈夫曼编码方法。哈夫曼编码给我们提供了一个简单有效的压缩数据的方式,在现实中使用广泛。
以下是具体代码。
//coder.cpp
#include
#include
#include "Coder.h"
/***********************
构建哈夫曼树及哈夫曼编码
*************************/
void BuildHuffmanTree( HuffmanTree &HT, //哈夫曼树
HuffmanCode &HC, //哈夫曼编码数组
unsigned int *w, //字符的权值数组
unsigned int n //待编码的字符数量
)
{
if (n <=1 ) return;
unsigned int m = 2 * n - 1; //生成的哈夫曼树的结点数量
HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); //未使用0号存储单位
HT->weight = m;
unsigned int i;
HuffmanTree p;
for (p = HT + 1, i = 1; i <= n; ++i, ++p, ++w){
p->lChild = 0;
p->rChild = 0;
p->weight = (unsigned int)*w;
p->parent = 0;
} //初始化哈夫曼树的数组存储结构//
for (; i <= m; ++i, ++p){
p->lChild = 0;
p->rChild = 0;
p->weight = 0;
p->parent = 0;
}//即构造初态
for (i = n + 1; i <= m; ++i) {
unsigned int s1, s2;
Select(HT, i - 1, s1, s2);
HT[s1].parent = HT[s2].parent = i;
HT[i].lChild = s1;
HT[i].rChild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
//----------从叶子到根逆向求每个字符的哈夫曼编码------------
HC = (HuffmanCode)malloc((n + 1) * sizeof(char *)); //未使用0号存储单元
char * cd = 0;
HC[0] = (char *)n; //利用空闲的0号存储单元,保存HC申请的存储单元数
cd = (char *)malloc(n * sizeof(c