哈夫曼编码

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

南京工程学院

通信工程学院

《信息论与编码》大作业课程名称信息论与编码学生班级电子信息121

学生姓名顾健

实验成绩评定

指导教师签字

年月日

基于C++语言的哈夫曼(Haffman)编码

哈夫曼(Haffman)编码是一种常用的压缩编码方法,是哈夫曼于1952年为压缩文本文件建立的。它的基本原理是按照概率大小顺序排列信源符号,并设法按逆顺序分配码字字长,使编码的码字为可辨识的。哈夫曼码是最佳码。

二进制哈夫曼码的编码步骤如下:

(1) 将q 个信源符号按概率分布)(i s p 的大小,以递减次序排列起来,设q p p p p ≥•••≥≥≥321

(2) 用0和1码符号分别代表概率最小的两个信源符号,并将这两个概率最小的信源符号合并成一个符号,从而得到只包含q-1个符号的新信源,称为S 信源的缩减信源1S 。

(3) 把缩减信源1S 的符号仍按概率大小以递减次序排列,再将最后两个概率最小的符号合并成一个符号,并分别用0和1码符号表示,这样又形成了q-2个符号的缩减信源2S 。

(4) 依此继续下去,直至最后只剩两个符号为止。将这最后两个信源符号分别用0和1码符号表示。然后从最后一级缩减信源开始,向前返回,就得出各信源符号所对应的码符号序列,即对应的码字。

下面举一个具体的Huffman 编码的例子(如图1所示):

信源符号 概率 信源缩减过程 编码 码长

1S 0.4 00 2

2S 0.2 10 2 3S 0.2 11 2 4S 010 3 5S 011 3 图1 Huffman 编码示例

它的平均码长为

)/(2.2305.0315.022.022.024.0)(5

1信源符号码符号=⨯+⨯+⨯+⨯+⨯=∑==i i i l s p L 信息熵为

)/(08.2)log()(-)(5

1信源符号比特=∑==i i i s s p S H 编码效率为

%5.94%1002

.208.2)(=⨯==L S H η 哈夫曼编码方法得到的码并非是唯一的。造成非唯一的原因是:

(1) 任意的,每次对信源缩减时,赋予信源最后两个概率最小的符号,用0和1是可以任意

的,所以可以得到不同的哈夫曼码,但不会影响码字的长度。

(2) 对信源进行缩减时,两个概率最小的符号合并后的概率与其他信源符号的概率相同时,这两者在缩减信源中进行概率排序,其位置放置次序是可以任意的,故会得到不同的哈夫曼码。此时将影响码字的长度,一般将合并的概率放在上面,这样可获得较小的码方差。 算法的实现:

(1) 对于Huffman 编码问题,在构造Huffman 树时,要求能方便地实现从父结点到左右孩子结点的操作,在进行Huffman 编码时,又要求能方便地实现从孩子结点到父结点的操作。因此,设计Huffman 树的结点存储结构为父亲孩子存储结构。

根据数据结构理论可知,二叉数结点的父亲孩子存储结构可用仿真指针实现。另外,每个结点还要有权值域。其元素结构如下:

由Huffman 编码过程可见,从Huffman 树求叶子结点的Huffman 编码实际上是从叶子结点到根结点路径分支的逐个遍历,每经过一个分支就得到一位Huffman 编码值。因此,需要一个数组bit[MaxBit]保存每个叶子结点到根结点路径所对应的Huffman 编码。由于是不等长编码,需要一个数据域len 表示每个Huffman 编码的长度。这样,每个叶子结点的Huffman 编码是从数组bit 的起始位置start 开始到数组结束位置中存放的0到1的序列,data

1) 定义哈夫曼树的结点结构huffnode 。

2) 定义哈夫曼编码的结构huffcode 。

3) 数组初始化。

4) 构造哈夫曼树。

① 构造n 棵只有一个根结点的二叉树,并找出根结点权值最小的两棵树;

② 将找出的两棵树合并为一颗子树。

5) 求各字符的哈夫曼编码。

6) 输出字符的哈夫曼编码。

要求:对任意的符号序列进行哈夫曼编码,并给出编码效率。

哈夫曼编码的c++程序:

/*******************哈夫曼编码

*******************/

#include

#include

#include

#define n 100

#define m 2*n-1

//码结点的存储结构

typedef struct

{

char ch;

char bits[9];

int len;

}CodeNode;

typedef CodeNode HuffmanCode[n+1];

//树结点的存储结构

typedef struct

{

int weight;

int lchild,rchild,parent;

}HTNode;

typedef HTNode HuffmanTree[m+1];

int num;

//挑选权值最小的两个结点

void select(HuffmanTree HT,int k,int &s1,int &s2)

{

int i,j;

int minl=32767;

for(i=1;i<=k;i++)

if(HT[i].weight

{

j=i;

minl=HT[i].weight;

}

s1=j;

minl=32767;

for(i=1;i<=k;i++)

if(HT[i].weight

{

j=i;

minl=HT[i].weight;

}

s2=j;

}

//统计输入字符和串

int jsq(char *s,int cnt[],char str[])

{

char *p;

int i,j,k=0;

int temp[257];

for(i=0;i<257;i++)

temp[i]=0;

for(p=s;*p!='\0';p++)

temp[*p]++;

for(i=0,j=0;i<=256;i++)

if(temp[i]!=0)

{

相关文档
最新文档