搜档网
当前位置:搜档网 › 利用哈夫曼编码实现压缩和解压缩

利用哈夫曼编码实现压缩和解压缩

利用哈夫曼编码实现压缩和解压缩
利用哈夫曼编码实现压缩和解压缩

利用哈夫曼编码实现压缩和解压缩

1.问题描述

利用哈夫曼编码,实现压缩和解压缩的数据元素具有如下形式:

结点:

weight:存储结点的权值

parent:是结点双亲在向量中的下标

lchild:结点的左儿子向量下标

rchild:结点右儿子向量下标

bits:位串,存放编码

ch:字符

start:编码在位串中的起始位置

文件操作记录:

b:记录字符在数组中的位置

count:字符出现频率(权值)

lch、rch、parent:定义哈夫曼树指针变量

bits[256]:定义存储哈夫曼编码的数组

2.功能需求

对于给定的一组字符,可以根据其权值进行哈夫曼编码,并能输出对应的哈夫曼树和哈夫曼编码;实现哈夫曼解码。能够分析文件,统计文件中出现的字符,再对文件进行编码,实现文件的压缩和解压缩,能够对于文件的压缩,比例进行统计,能够打印文件。

3.实现要点

(1)构造哈弗曼树过程中,首先将初始森林的各根结点的双亲和左、右儿子指针置-1;叶子在向量T的前n个分量中,构成初始森林的n个结点;对森林中的树进行n次合并,并产生n-1个新结点,依次放入向量T的第i个分量中。

(2)编码过程中,从叶子T[i]出发,利用双亲的指针找到双亲T[p];再根据T[p]的

孩子指针可以知道T[i]是T[p]的左儿子还是右儿子,若是左儿子,则生成代码0,否则生成代码1;

(3)在文件压缩和解压过程中,主要参考网上资料,每个步骤都基本理解,并注上了详细解析。

4.函数定义

功能:输入权重,构造一棵哈弗曼树

void huffman(hftree T)

{

if(n<1 || n > m)return;

int i,j,p1,p2;

float small1,small2;

//初始化

cout<<"请输入叶子权重(5个):"<

for(i=0; i

{

T[i].parent = -1;

T[i].lchild = T[i].rchild = -1;

}

//输入叶子权值

for(i=0; i

{

cin>>T[i].weight;

}

for(i=n; i

{

p1 = p2 = -1;

small1 = small2 = MAX_FLOAT;

for(j=0; j<=i-1; j++)

{

if(T[j].parent != -1)continue;

if(T[j].weight < small1)

{

small2 = small1;

small1 = T[j].weight;

p2 = p1;

p1 = j;

}

else if(T[j].weight < small2)

{

small2 = T[j].weight;

p2 = j;

}

}

T[p1].parent = T[p2].parent = i;

T[i].parent=-1;

T[i].lchild=p1;

T[i].rchild=p2;

T[i].weight=small1 + small2;

}

cout<<"创建成功!"<

}

功能:对哈弗曼树进行编码

void encode(codelist codes, hftree T)

{

int i,c,p,start;

cout<<"请输入需要编码的字符(5个):"<

for(i=0; i

{

cin>>codes[i].ch;

start=n;

c=i;

p=T[i].parent;

while(p!=-1)

{

start--;

if(T[p].lchild==c) codes[i].bits[start]='0';

else codes[i].bits[start]='1';

c=p;

p=T[p].parent;

}

codes[i].start=start;

}

cout<<"输入成功!:"<

cout<<"编码表:"<

for(int x=0; x

{

cout<

for(int q=codes[x].start;q

cout<

}

}

函数功能:对哈弗曼树进行解码

void decode(codelist codes,hftree T) {

int i,c,p,b;

int endflag;

endflag=-1;

i=m-1;

while(cin>>b,b!=endflag)

{

if(b==0) i=T[i].lchild;

else i=T[i].rchild;

if(T[i].lchild==-1)

{

cout<

i=m-1;

}

}

if(i!=m-1)cout<<"编码有错!\n";

}

功能:对文件进行压缩,统计压缩率

void compress()

{

char filename[255],outputfile[255],buf[512];

unsigned char c;

long i,j,m,n,f;

long min1,pt1,flength,length1,length2;

double div;

FILE *ifp,*ofp;

cout<<"\t请您输入需要压缩的文件:";

cin>>filename;

ifp=fopen(filename,"rb");

if(ifp==NULL)

{

cout<<"\n\t文件打开失败!\n\n";

return;

}

cout<<"\t请您输入压缩后的文件名:";

cin>>outputfile;

ofp=fopen(strcat(outputfile,".encode"),"wb");

if(ofp==NULL)

{

cout<<"\n\t压缩文件失败!\n\n";

return;

}

flength=0;

while(!feof(ifp))

{

fread(&c,1,1,ifp);

header[c].count++; //字符重复出现频率+1

flength++; //字符出现原文件长度+1

}

flength--;

length1=flength; //原文件长度用作求压缩率的分母

header[c].count--;

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

{

if(header[i].count!=0) header[i].b=(unsigned char)i;

else header[i].b=0;

header[i].parent=-1;header[i].lch=header[i].rch=-1; //对结点进行初始化

}

for(i=0;i<256;i++) //根据频率(权值)大小,对结点进行排序,选择较小的结点进树

{

for(j=i+1;j<256;j++)

{

if(header[i].count

{

tmp=header[i];

header[i]=header[j];

header[j]=tmp;

}

}

}

for(i=0;i<256;i++) if(header[i].count==0) break;

n=i; //外部叶子结点数为n个时,内部结点数为n-1,整个哈夫曼树的需要的结点数为2*n-1.

m=2*n-1;

for(i=n;i

{

min1=999999999; //预设的最大权值,即结点出现的最大次数

for(j=0;j

{

if(header[j].parent!=-1) continue;

//parent!=-1说明该结点已存在哈夫曼树中,跳出循环重新选择新结点*/

if(min1>header[j].count)

{

pt1=j;

min1=header[j].count;

continue;

}

}

header[i].count=header[pt1].count;

header[pt1].parent=i; //依据parent域值(结点层数)确定树中结点之间的关系

header[i].lch=pt1; //计算左分支权值大小

min1=999999999;

for(j=0;j

{

if(header[j].parent!=-1) continue;

if(min1>header[j].count)

{

pt1=j;

min1=header[j].count;

continue;

}

}

header[i].count+=header[pt1].count;

header[i].rch=pt1; //计算右分支权值大小

header[pt1].parent=i;

}

for(i=0;i

{

f=i;

header[i].bits[0]=0; //根结点编码0

while(header[f].parent!=-1)

{

j=f;

f=header[f].parent;

if(header[f].lch==j) //置左分支编码0

{

j=strlen(header[i].bits);

memmove(header[i].bits+1,header[i].bits,j+1);

//依次存储连接“0”“1”编码

header[i].bits[0]='0';

}

else //置右分支编码1

{

j=strlen(header[i].bits);

memmove(header[i].bits+1,header[i].bits,j+1);

header[i].bits[0]='1';

}

}

}

fseek(ifp,0,SEEK_SET); //从文件开始位置向前移动0字节,即定位到文件开始位置

fwrite(&flength,sizeof(int),1,ofp);

fseek(ofp,8,SEEK_SET);

buf[0]=0; //定义缓冲区,它的二进制表示00000000

f=0;

pt1=8;

while(!feof(ifp))

{

c=fgetc(ifp);

f++;

for(i=0;i

{

if(c==header[i].b) break;

}

strcat(buf,header[i].bits);

j=strlen(buf);

c=0;

while(j>=8) //对哈夫曼编码位操作进行压缩存储

{

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

{

if(buf[i]=='1') c=(c<<1)|1;

else c=c<<1;

}

fwrite(&c,1,1,ofp);

pt1++; //统计压缩后文件的长度

strcpy(buf,buf+8); //一个字节一个字节拼接

j=strlen(buf);

}

if(f==flength) break;

}

if(j>0) //对哈夫曼编码位操作进行压缩存储

{

strcat(buf,"00000000");

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

{

if(buf[i]=='1') c=(c<<1)|1;

else c=c<<1;

}

fwrite(&c,1,1,ofp);

pt1++;

}

fseek(ofp,4,SEEK_SET);

fwrite(&pt1,sizeof(long),1,ofp);

fseek(ofp,pt1,SEEK_SET);

fwrite(&n,sizeof(long),1,ofp);

for(i=0;i

{

fwrite(&(header[i].b),1,1,ofp);

c=strlen(header[i].bits);

fwrite(&c,1,1,ofp);

j=strlen(header[i].bits);

if(j%8!=0) //若存储的位数不是8的倍数,则补0 {

for(f=j%8;f<8;f++)

strcat(header[i].bits,"0");

}

while(header[i].bits[0]!=0)

{

c=0;

for(j=0;j<8;j++) //字符的有效存储不超过8位,则对有效位数左移实现两字符编码的连接

{

if(header[i].bits[j]=='1') c=(c<<1)|1; //|1不改变原位置上的“0”“1”值

else c=c<<1;

}

strcpy(header[i].bits,header[i].bits+8); //把字符的编码按原先存储顺序连接

fwrite(&c,1,1,ofp);

}

}

length2=pt1--;

div=((double)length1-(double)length2)/(double)length1; //计算文件的压缩率

fclose(ifp);

fclose(ofp);

printf("\n\t压缩文件成功!\n");

printf("\t压缩率为 %f%%\n\n",div*100);

return;

}

函数功能:对文件解压缩

void uncompress()

{

char filename[255],outputfile[255],buf[255],bx[255];

unsigned char c;

long i,j,m,n,f,p,l;

long flength;

FILE *ifp,*ofp;

cout<<"\t请您输入需要解压缩的文件:";

cin>>filename;

ifp=fopen(strcat(filename,".encode"),"rb");

if(ifp==NULL)

{

cout<<"\n\t文件打开失败!\n";

return;

}

cout<<"\t请您输入解压缩后的文件名:";

cin>>outputfile;

ofp=fopen(outputfile,"wb");

if(ofp==NULL)

{

cout<<"\n\t解压缩文件失败!\n";

return;

}

fread(&flength,sizeof(long),1,ifp); //读取原文件长度,对文件进行定位

fread(&f,sizeof(long),1,ifp);

fseek(ifp,f,SEEK_SET);

fread(&n,sizeof(long),1,ifp);

for(i=0;i

{

fread(&header[i].b,1,1,ifp);

fread(&c,1,1,ifp);

p=(long)c; //读取原文件字符的权值

header[i].count=p;

header[i].bits[0]=0;

if(p%8>0) m=p/8+1;

else m=p/8;

for(j=0;j

{

fread(&c,1,1,ifp);

f=c;

itoa(f,buf,2); //将f转换为二进制表示的字符串

f=strlen(buf);

for(l=8;l>f;l--)

{

strcat(header[i].bits,"0");

}

strcat(header[i].bits,buf);

}

header[i].bits[p]=0;

}

for(i=0;i

{

for(j=i+1;j

{

if(strlen(header[i].bits)>strlen(header[j].bits))

{

tmp=header[i];

header[i]=header[j];

header[j]=tmp;

}

}

}

p=strlen(header[n-1].bits);

fseek(ifp,8,SEEK_SET);

m=0;

bx[0]=0;

while(1) //通过哈夫曼编码的长短,依次解码,从原来的位存储还原到字节存储

{

while(strlen(bx)<(unsigned int)p)

{

fread(&c,1,1,ifp);

f=c;

itoa(f,buf,2);

f=strlen(buf);

for(l=8;l>f;l--) //在单字节内对相应位置补0

{

strcat(bx,"0");

}

strcat(bx,buf);

}

for(i=0;i

{

if(memcmp(header[i].bits,bx,header[i].count)==0) break;

}

strcpy(bx,bx+header[i].count);

c=header[i].b;

fwrite(&c,1,1,ofp);

m++; //统计解压缩后文件的长度

if(m==flength) break; //flength是原文件长度

}

fclose(ifp);

fclose(ofp);

cout<<"\n\t解压缩文件成功!\n";

if(m==flength) //对解压缩后文件和原文件相同性比较进行判断(根据文件大小)

cout<<"\t解压缩文件与原文件相同!\n\n";

else cout<<"\t解压缩文件与原文件不同!\n\n";

return;

}

5、总结和体会

本次大作业与C++大作业有所不同,主要是利用构造数据结构解决问题,C++大作业主要体现类和文件读写功能。有些同学这次用了可视化来完成,我觉得没必要。因为数据结构主要理解一个事物的结构,然后利用链表之类的结构保存信息,再利用算法解决问题。可视化的对象化性太强了,用可视化实现反而把数据结构这个重点忽视。

这次选择哈弗曼树的实现是因为想了解压缩技术,并且希望能用到自己的软件中。但是由于理解能力有限,只能参考书本把基本功能实现。书本的知识理解了,但是还不能自己构建一个更加符合要求的程序。最后到网上寻找了很多相关资料,参考了部分代码,实现了文件压缩解压功能。

哈夫曼树编码译码实验报告(DOC)

数据结构课程设计设计题目:哈夫曼树编码译码

目录 第一章需求分析 (1) 第二章设计要求 (1) 第三章概要设计 (2) (1)其主要流程图如图1-1所示。 (3) (2)设计包含的几个方面 (4) 第四章详细设计 (4) (1)①哈夫曼树的存储结构描述为: (4) (2)哈弗曼编码 (5) (3)哈弗曼译码 (7) (4)主函数 (8) (5)显示部分源程序: (8) 第五章调试结果 (10) 第六章心得体会 (12) 第七章参考文献 (12) 附录: (12)

在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是哈夫曼编码。哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。 第二章设计要求 对输入的一串电文字符实现哈夫曼编码,再对哈夫曼编码生成的代码串进行译码,输出电文字符串。通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度能尽可能短,即采用最短码。假设每种字符在电文中出现的次数为Wi,编码长度为Li,电文中有n种字符,则电文编码总长度为∑WiLi。若将此对应到二叉树上,Wi为叶结点的权,Li为根结点到叶结点的路径长度。那么,∑WiLi 恰好为二叉树上带权路径长度。因此,设计电文总长最短的二进制前缀编码,就是以n种字符出现的频率作权,构造一棵哈夫曼树,此构造过程称为哈夫曼编码。设计实现的功能: (1) 哈夫曼树的建立; (2) 哈夫曼编码的生成; (3) 编码文件的译码。

哈夫曼编码程序设计

算法与数据结构课程设计哈夫曼编码/译码器设计 学生姓名: 学号: 专业:(计算机科学与技术) 年级:(大二) 指导教师:(汪洋) 2009年6月19日 哈夫曼编码/译码器

问题描述: 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本,但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道)每端都需要一个完整的编/译码系统。试为这样的信息收发站写一哈夫曼编/译码系统。 基本要求: I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。 E:编码(Encoding)。利用已建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。 D:译码(Decoding)。利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件TextFile中。 P:打印代码文件(Print)。将文件CodeFile以紧凑格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件CodePrin中。 T:打印哈夫曼树(Tree printing)。将已在中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。 大体解题思路: (1)对输入的一段欲编码的字符串进行统计各个字符出现的次数,并它们转化为权值{w1,w2,……,wN}构成n棵二叉树的集合F={T1,T2,……,Tn}把它们保存到结构体数组HT[n]中,其中{Ti是按它们的ASCⅡ码值先后排序。其中每棵二叉树Ti中只有一个带权为Wi的根结点的权值为其左、右子树上根结点的权值之和。 (2)在HT[1..i]中选取两棵根结点的权值最小且没有被选过的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为左、右子树上根结点的权值之和。 (3)哈夫曼树已经建立后,从叶子到根逆向求每一个字符的哈夫曼编码。 概要设计: 实现的功能:1.查看原文(showpassage()),2.字符统计(showdetail()),

哈夫曼编码与译码的实现

数据结构课程设计评阅书

2011—2012学年第一学期 专业:信息管理与信息系统学号: 1021024016 姓名:万永馨 课程设计名称:数据结构课程设计 设计题目:哈夫曼编码与译码的实现 完成期限:自 2012 年 2 月 20 日至 2012 年 3 月 2 日共 2 周 设计依据、要求及主要内容(可另加附页): 该设计题目将按以下要求完成: 哈夫曼编码与译码是信息传输中应用的经典算法,运用C或VC++结合数据结构等基础知识,按 以下要求编程实现各种进制的转换。 任务要求:1)阐述设计思想,画出流程图;2)需要对哈夫曼编码/译码的相关原理有所了解,设计数 据结构,建立必要的信息数据文件(最好存储成外部文件),并分析完成用户所需的基本操作功能;3)实现给定信息的编码和译码功能;4)应有较好的界面设计,说明程序测试方法;5)按照格式要 求完成课程设计说明书。 设计要求: 1)问题分析和任务定义:根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么?(而不是怎么做?)限制条件是什么?确定问题的输入数据集合。 2)逻辑设计:对问题描述中涉及的操作对象定义相应的数据类型,并按照以数据结构为中心的 原则划分模块,定义主程序模块和各抽象数据类型。逻辑设计的结果应写出每个抽象数据类型的定 义(包括数据结构的描述和每个基本操作的功能说明),各个主要模块的算法,并画出模块之间的调 用关系图; 3)详细设计:定义相应的存储结构并写出各函数的伪码算法。在这个过程中,要综合考虑系统 功能,使得系统结构清晰、合理、简单和易于调试,抽象数据类型的实现尽可能做到数据封装,基 本操作的规格说明尽可能明确具体。详细设计的结果是对数据结构和基本操作做出进一步的求精, 写出数据存储结构的类型定义,写出函数形式的算法框架; 4)程序编码:把详细设计的结果进一步求精为程序设计语言程序。同时加入一些注解和断言, 使程序中逻辑概念清楚; 5)程序调试与测试:能够熟练掌握调试工具的各种功能,设计测试数据确保程序正确。调试正 确后,认真整理源程序及其注释,形成格式和风格良好的源程序清单和结果; 6)结果分析:程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果。算 法的时间、空间复杂性分析; 7)编写课程设计报告; 以上要求前三个阶段的任务完成后,将设计说明书的草稿交指导老师面审,审查合格方可进入 后续阶段的工作。设计工作结束,经指导老师验收合格后将设计说明书装订,并答辩。

数据结构课程设计哈夫曼编码-2

数据结构课程设计哈夫曼编码-2

《数据结构与算法》课程设计 目录 一、前言 1.摘要 2.《数据结构与算法》课程设计任务书 二、实验目的 三、题目--赫夫曼编码/译码器 1.问题描述 2.基本要求 3.测试要求 4.实现提示 四、需求分析--具体要求 五、概要设计 六、程序说明 七、详细设计 八、实验心得与体会

前言 1.摘要 随着计算机的普遍应用与日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及设计最短路线等复杂的非数值处理和操作。算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。 算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。 数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。数据结构有逻辑上的数据结构和物理上的数据结构之分。逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。数据结构是数据存在的形式。 《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。 学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。

哈夫曼树的编码和译码

#include"stdafx.h" #include"stdio.h" #include"conio.h" #include #include #include using namespace std; #define maxbit 100 #define Maxvalue 2000//最大权值整数常量#define Maxleaf 100//最大叶子结点数 #define size 300//0、串数组的长度 static int n;//实际的叶子结点数 struct HNodeType { int weight; int parent; int lchild; int rchild; int ceng;//结点相应的层数 char ch;//各结点对应的字符 }; struct HCodeType { int bit[maxbit];//存放编码的数组 int start;//编码在数组中的开始位置}; static HNodeType *HuffNode;//定义静态指针HNodeType *init()//初始化静态链表 { HuffNode=new HNodeType[2*n-1]; for(int i=0;i<2*n-1;i++) { HuffNode[i].weight=0; HuffNode[i].parent=-1; HuffNode[i].lchild=-1; HuffNode[i].rchild=-1; HuffNode[i].ceng=-1; HuffNode[i].ch='0'; } return HuffNode; }

哈夫曼编码步骤

哈夫曼编码步骤: 一、对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F= {T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算法,一般还要求以Ti的权值Wi的升序排列。) 二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。 三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。 四、重复二和三两步,直到集合F中只有一棵二叉树为止。 /*------------------------------------------------------------------------- * Name: 哈夫曼编码源代码。 * Date: 2011.04.16 * Author: Jeffrey Hill+Jezze(解码部分) * 在Win-TC 下测试通过 * 实现过程:着先通过HuffmanTree() 函数构造哈夫曼树,然后在主函数main()中 * 自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在 * 父结点左侧,则置码为0,若在右侧,则置码为1。最后输出生成的编码。*------------------------------------------------------------------------*/ #include #include #define MAXBIT 100 #define MAXVALUE 10000 #define MAXLEAF 30 #define MAXNODE MAXLEAF*2 -1 typedef struct { int bit[MAXBIT]; int start;} HCodeType; /* 编码结构体*/ typedef struct{ int weight; int parent; int lchild; int rchild; int value;} HNodeType; /* 结点结构体*/ /* 构造一颗哈夫曼树*/ void HuffmanTree (HNodeType HuffNode[MAXNODE], int n){ /* i、j:循环变量,m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值,x1、x2:构造哈夫曼树不同过程中两个最小权值结点在数组中的序号。*/ int i, j, m1, m2, x1, x2; /* 初始化存放哈夫曼树数组HuffNode[] 中的结点*/ for (i=0; i<2*n-1; i++)

数据结构课程设计哈夫曼编码(DOC)

《数据结构与算法》课程设计(2009/2010学年第二学期第20周) 指导教师:王老师 班级:计算机科学与技术(3)班 学号: 姓名:

《数据结构与算法》课程设计 目录 一、前言 1.摘要 2.《数据结构与算法》课程设计任务书 二、实验目的 三、题目--赫夫曼编码/译码器 1.问题描述 2.基本要求 3.测试要求 4.实现提示 四、需求分析--具体要求 五、概要设计 六、程序说明 七、详细设计 八、实验心得与体会

前言 1.摘要 随着计算机的普遍应用与日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及设计最短路线等复杂的非数值处理和操作。算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。 算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。 数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。数据结构有逻辑上的数据结构和物理上的数据结构之分。逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。数据结构是数据存在的形式。 《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。 学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。 2.《数据结构与算法》课程设计任务书 《数据结构与算法》是计算机专业重要的核心课程之一,在计算机专业的学习过程中占有非常重要的地位。《数据结构与算法课程设计》就是要运用本课程以及到目前为止的有关课程中的知识和技术来解决实际问题。特别是面临非数值计算类型的应用问题时,需要选择适当的数据结构,设计出满足一定时间和空间限制的有效算法。 本课程设计要求同学独立完成一个较为完整的应用需求分析。并在设计和编写具有一定规模程序的过程中,深化对《数据结构与算法》课程中基本概念、理论和方法的理解;训练综合运用所学知识处理实际问题的能力,强化面向对象的程序设计理念;使自己的程序设计与调试水平有一个明显的提高。

哈夫曼编码与译码器_数据结构课程设计报告

沈阳航空航天大学 课程设计报告 课程设计名称:数据结构课程设计 课程设计题目:实现哈夫曼编码和译码器 院(系):计算机学院 专业:计算机科学与技术 班级:24010102 学号:2012040101082 姓名:尹伟和 指导教师:徐蕾

此页为任务书

目录 1.题目分析 (1) 1.1.题目重述 (1) 1.1.1.系统功能需求分析 (1) 2.程序设计 (2) 2.1.系统功能模块说明 (2) 2.1.1.系统功能模块结构 (2) 2.1.2.系统模块功能说明 (3) 2.2.数据结构说明 (3) 2.2.1.结构体定义说明 (3) 2.2.2.哈夫曼树 (4) 2.2.3.字符-哈夫曼编码对照表 (4) 2.3.函数说明 (4) 3.算法描述 (6) 3.1.哈夫曼树的构建 (6) 3.2.字符-哈夫曼编码对照表 (6) 3.3.编码 (6) 3.4.译码 (7) 4.程序测试 (9) 4.1.字符集输入 (9) 4.2.编码测试 (10) 4.3.译码测试 (11) 参考文献 (13) 附录(程序清单) (14)

沈阳航空航天大学课程设计报告 1.题目分析 1.1.题目重述 本次课程设计的目标是实现一个哈夫曼编码和译码器。该哈夫曼编码和译码器需要根据用户输入的字符集及相应字符出现的频率,对字符集所包含的字符进行哈夫曼编码。同时,作为编码器需要其对用户提供的明文字符串进行编码,使明文字符串变为二进制密文;作为译码器需要对用户提供的二进制密文进行译码,使二进制密文变为字符明文。 1.1.1.系统功能需求分析 通过对课程设计的题目分析,可以得出哈夫曼编码和译码器的功能需求,需求如下: 1)读取用户输入的字符集和相应字符出现的频率; 2)根据用户输入构建哈夫曼树; 3)根据哈夫曼树构建字符-哈夫曼编码对照表; 4)根据字符-哈夫曼编码对照表对明文字符串进行编码; 5)根据哈夫曼树对二进制密文进行译码。

基于哈夫曼编码的图像编解码系统设计及实现

课程设计任务书 题目:基于哈夫曼编码的图像编解码系统设计及实现 初始条件: 计算机 Windows8操作系统 MATLAB7.8.0软件 要求完成的主要任务: 设计哈夫曼编码的图像编解码系统、利用软件编写程序、仿真实现 时间安排: 第1-18周:理论讲解 第19周:理论设计,实验室安装调试以及撰写设计报告 答辩: 时间:7月2日 地点: 鉴主15楼通信实验室四 指导教师签名:年月日 系主任(或责任教师)签名:年月日

目录 目录........................................................................................................................ I矚慫润厲钐瘗睞枥庑赖。摘要....................................................................................................................... I I聞創沟燴鐺險爱氇谴净。ABSTRACT ......................................................................................................... I II残骛楼諍锩瀨濟溆塹籟。1引言..................................................................................................................... 1酽锕极額閉镇桧猪訣锥。 1.1图像数据压缩的目的.............................................................................. 1彈贸摄尔霁毙攬砖卤庑。 1.2图像数据压缩的原理.............................................................................. 1謀荞抟箧飆鐸怼类蒋薔。 1.3常用的压缩编码方法.............................................................................. 3厦礴恳蹒骈時盡继價骚。2哈夫曼编码......................................................................................................... 3茕桢广鳓鯡选块网羈泪。 2.1 哈夫曼编码简介..................................................................................... 3鹅娅尽損鹌惨歷茏鴛賴。 2.2哈夫曼编码步骤...................................................................................... 3籟丛妈羥为贍偾蛏练淨。 2.3 哈夫曼编码的缺点................................................................................. 5預頌圣鉉儐歲龈讶骅籴。3基于哈夫曼编码的图像编解码系统的程序设计............................................. 6渗釤呛俨匀谔鱉调硯錦。 3.1 分块程序设计分析................................................................................. 6铙誅卧泻噦圣骋贶頂廡。 3.2主程序...................................................................................................... 8擁締凤袜备訊顎轮烂蔷。 3.3程序函数.................................................................................................. 9贓熱俣阃歲匱阊邺镓騷。 3.3.1编码函数....................................................................................... 9坛摶乡囂忏蒌鍥铃氈淚。 3.3.2解码函数..................................................................................... 12蜡變黲癟報伥铉锚鈰赘。 3.3.3符号概率计算函数..................................................................... 14買鲷鴯譖昙膚遙闫撷凄。 3.3.4节点添加函数............................................................................. 14綾镝鯛駕櫬鹕踪韦辚糴。 3.3.5解码返回符号函数..................................................................... 15驅踬髏彦浃绥譎饴憂锦。4系统仿真结果................................................................................................... 15猫虿驢绘燈鮒诛髅貺庑。 4.1程序运行结果........................................................................................ 15锹籁饗迳琐筆襖鸥娅薔。 4.2 程序运行结果分析............................................................................... 17構氽頑黉碩饨荠龈话骛。 5.总结................................................................................................................... 18輒峄陽檉簖疖網儂號泶。参考文献.............................................................................................................. 19尧侧閆繭絳闕绚勵蜆贅。

huffman编码译码实现文件的压缩与解压.

数据结构 课程设计 题目名称:huffman编码与解码实现文件的压缩与解压专业年级: 组长: 小组成员: 指导教师: 二〇一二年十二月二十六日

目录 一、目标任务与问题分析 (2) 1.1目标任务 (2) 1.2问题分析 (2) 二、算法分析 (2) 2.1构造huffman树 (2) 2.1.1 字符的统计 (2) 2.1.2 huffman树节点的设计 (2) 2.2构造huffman编码 (3) 2.2.1 huffman编码的设计 (3) 2.3 压缩文件与解压文件的实现 (3) 三、执行效果 (4) 3.1界面 (4) 3.2每个字符的编码 (4) 3.3操作部分 (5) 3.4文件效果 (6) 四、源程序 (7) 五、参考文献 (16)

huffman编码与解码实现文件的压缩与解压 一、目标任务与问题分析 1.1目标任务 采用huffman编码思想实现文件的压缩和解压功能,可以将任意文件压缩,压缩后也可以解压出来。这样即节约了存储空间,也不会破坏文件的完整性。 1.2问题分析 本问题首先应该是利用哈夫曼思想,对需要压缩的文件中的个字符进行频率统计,为了能对任意的文件进行处理,应该所有的文件以二进制的方式进行处理,即对文件(不管包含的是字母还是汉字)采取一个个的字节处理,然后根据统计的频率结果构造哈夫曼树,然后对每个字符进行哈夫曼编码,然后逐一对被压缩的文件的每个字符构建的新的哈夫曼编码存入新的文件中即得到的压缩文件。解压过程则利用相应的哈夫曼树及压缩文件中的二进制码将编码序列译码,对文件进行解压,得到解压文件。 二、算法分析 2.1构造huffman树 要利用哈夫曼编码对文本文件进行压缩,首先必须知道期字符相应的哈夫曼编码。为了得到文件中字符的频率,一般的做法是扫描整个文本进行统计,编写程序统计文件中各个字符出现的频率。由于一个字符的范围在[0-255]之间,即共256个状态,所以可以直接用256个哈夫曼树节点即数组(后面有节点的定义)空间来存储整个文件的信息,节点中包括对应字符信息,其中包括频率。 2.1.1 字符的统计 用结构体huffchar来存放文件字符的信息。其中有文件中不同字符出现的种类Count、字符data。 struct huffchar{ //存放读入字符的类; int Count;//字符出现的个数; char data;//字符; }; 函数实现: bool char_judge(char c)//判断字符出现的函数; void char_add(char c)//添加新出现的字符; void read_file_count() //文件的读取 2.1.2 huffman树节点的设计 用结构体huff_tree来存储结点信息,其中有成员频率weight、父亲节点parent、左儿子节点lchild、右儿子节点rchild。

哈夫曼编码译码系统课程设计实验报告(含源代码C++_C语言)

目录 摘要………………………………………………………………………..………………II Abstract …………………………………………………………………………..………... II 第一章课题描述 (1) 1.1 问题描述 (1) 1.2 需求分析…………………………………………………..…………………………… 1 1.3 程序设计目标…………………………………………………………………………… 第二章设计简介及设计方案论述 (2) 2.1 设计简介 (2) 2.2 设计方案论述 (2) 2.3 概要设计 (2) 第三章详细设计 (4) 3.1 哈夫曼树 (4) 3.2哈夫曼算 法 (4) 3.2.1基本思 想 (4) 3.2.2存储结 构 (4)

3.3 哈夫曼编码 (5) 3.4 文件I/O 流 (6) 3.4.1 文件流 (6) 3.4.2 文件的打开与关闭 (7) 3.4.3 文件的读写 (7) 3..5 C语言文件处理方式…………………………………………………………………… 第四章设计结果及分析 (8) 4.1 设计系统功能 (8) 4.2 进行系统测试 (8) 总结 (13) 致谢 (14) 参考文献 (15) 附录主要程序代码 (16) 摘要 在这个信息高速发展的时代,每时每刻都在进行着大量信息的传递,到处都离不开信息,它贯穿在人们日常的生活生产之中,对人们的影响日趋扩大,而利用哈夫曼编码

进行通信则可以大大提高信道利用率,缩短信息传输时间,降低传输成本。在生产中则可以更大可能的降低成本从而获得更大的利润,这也是信息时代发展的趋势所在。本课程设计的目的是使学生学会分析待加工处理数据的特性,以便选择适当的逻辑结构、存储结构以及进行相应的算法设计。学生在学习数据结构和算法设计的同时,培养学生的抽象思维能力、逻辑推理能力和创造性的思维方法,增强分析问题和解决问题的能力。此次设计的哈夫曼编码译码系统,实现对给定报文的编码和译码,并且任意输入报文可以实现频数的统计,建立哈夫曼树以及编码译码的功能。这是一个拥有完备功能的系统程序,对将所学到的知识运用到实践中,具有很好的学习和研究价值. 关键词:信息;通讯;编码;译码;程序 Abstract This is a date that information speeding highly development and transmit

哈夫曼编码与译码报告

一、设计思想 程序要求: 利用哈夫曼树对字符串进行编码,要求每个字符有自己唯一的编码。将得到的一串字串译成0、1编码后存到一个文件夹中,然后再从这个文件夹中读出这串编码进行解码。 实现方法: 输入一串字符,要求字符的区间为大写的26个英文字母,将获得的串字符用计算权值的函数(jsquanzhi())进行字符统计,统计出现的字符种数以及每种字符出现的次数,将该种字符出现的次数作为它的权值。将出现的字符的权值和该字符依次分别赋给两个结构体HT和HC,利用HT(节点)权值的大小建立哈夫曼树,首先用选择函数select()函数选择两个权值最小的字符作为叶子节点,创建一个新的节点作为这两个叶节点的父节点,被选中的节点给他的HT[i].parent赋值是他下次不再被选中,父节点的权值为,子节点的权值之和。然后将该将父节点放入筛选区中,再进行选择(被选过的不再被使用),直到所有的节点都被使用,这样一个哈夫曼树就被建立了。根据每个字符在哈夫曼书中的位置来编译每个字符的0、1密文代码,从叶节点判断该叶节点是其父节点的左右字左字为‘0’,右子为‘1’,在判断父节点是上级父节点的左右子直至根节点,将生成的0、1字符串按所表示的字符倒序存入HC相应的字符的bins[]数组。 重新一个一个字符的读取输入的字符串,按照字符出现的顺序将它转为0、1代码并存到一个txt文件夹中去。解码时从文件夹中,一个一个字符的读出那串0、1代码赋给一个临时字符串cd[],用该字符串与每个字符的HC[i].bins密文比较,直到与一个字符的密文相同时,译出该字符,将字符存放在临时字符数组tempstr[]中,清空临时字符串继续读取0、1代码进行翻译,直至文件密文结束为止。于是就得到了原先被加密的那串字符串。

哈夫曼树和哈夫曼编码(数据结构程序设计)

课程设计 (数据结构) 哈夫曼树和哈夫曼编码 二○○九年六月二十六日课程设计任务书及成绩评定

课题名称表达式求值哈夫曼树和哈夫曼编码 Ⅰ、题目的目的和要求: 巩固和加深对数据结构的理解,通过上机实验、调试程序,加深对课本知识的理解,最终使学生能够熟练应用数据结构的知识写程序。 (1)通过本课程的学习,能熟练掌握几种基本数据结构的基本操作。 (2)能针对给定题目,选择相应的数据结构,分析并设计算法,进而给出问题的正确求解过程并编写代码实现。 Ⅱ、设计进度及完成情况 Ⅲ、主要参考文献及资料 [1] 严蔚敏数据结构(C语言版)清华大学出版社 1999

[2] 严蔚敏数据结构题集(C语言版)清华大学出版社 1999 [3] 谭浩强 C语言程序设计清华大学出版社 [4] 与所用编程环境相配套的C语言或C++相关的资料 Ⅳ、成绩评定: 设计成绩:(教师填写) 指导老师:(签字) 二○○九年六月二十六日

目录 第一章概述 (1) 第二章系统分析 (2) 第三章概要设计 (3) 第四章详细设计及实现代码 (8) 第五章调试过程中的问题及系统测试情况 (12) 第六章结束语 (13) 参考文献 (13)

第一章概述 课程设计是实践性教学中的一个重要环节,它以某一课程为基础,可以涉及和课程相关的各个方面,是一门独立于课程之外的特殊课程。课程设计是让同学们对所学的课程更全面的学习和应用,理解和掌握课程的相关知识。《数据结构》是一门重要的专业基础课,是计算机理论和应用的核心基础课程。 数据结构课程设计,要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面,加深对课程基本内容的理解。同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。 在这次的课程设计中我选择的题目是表达式求值和哈夫曼树及哈夫曼编码。这里我们介绍一种简单直观、广为使用的算法,通常称为“算符优先法”。哈夫曼树又称最优树,是一类带权路径长度最短的树,有着广泛的应用。 功能:表达式求值以栈为存储结构,实现输入的表达式的求值; 哈夫曼树和哈夫曼编码是实现最优二叉树的构造,并能通过最优二叉树进行编码,应用到电文中,并以此来译码。 利用键盘,输入相应的数值,通过程序实现表达式的求值;再利用键盘,输入各个顶点,通过程序构造最优二叉树以及为此编码。

哈夫曼编码和译码系统

通达学院 算法与数据结构程序设计 题目:哈夫曼编码和译码系统 专业 学生姓名 班级学号 指导教师 指导单位 日期

教师评语 同学出勤率(满勤、较高、一般,较低),学习态度(端正、较端正、一般、较差),程序设计基础(好、较好、一般、较差),演示程序(已经、没有)达到了基本要求,算法设计(好、较好、一般),界面友好程度(好、较好、一般),答辩过程中回答问题(准确、较准确、错误率较高),撰写报告格式(规范、一般)、内容(丰满、简单)、表述(清晰、一般、不清楚),(圆满、较好、基本)完成了课题任务。 教师签名: 年月日 成绩评定 备注

一、题目要求: 题 目 :哈夫曼编码和译码系统 基本要求: (1) 能输入字符集和各字符频度建立哈夫曼树; (2) 产生各字符的哈夫曼编码,并进行解码。 提高要求: (1) 能设计出简捷易操作的窗口界面; (2) 编码和译码存储在文件中。 二、需求分析: 2.1基本思想 根据,哈夫曼的定义,一棵二叉树要使其带权路径长度最小,必须使权值越大的叶子结点越靠近根结点,而权值越小的叶子结点越远离根结点.依据这个特点便提出了哈夫曼算法,其基本思想是: (1) 初始化:由给定的n 个权值{w 1, w 2,…, w n }构造n 棵只有一个根结点的二叉树,从而得到一个二叉树集合F={ T 1,T 2,…,T n }; (2) 选取与合并:在F 中选取根结点的权值最小的两棵二叉树分别作为左、右子树构造一颗新的二叉树,这棵新二叉树的根结点的权值为其左、右子树根结点的权值之和; (3) 删除与加入:在F 中删除作为左、右子树的两棵二叉树,并将新建立的二叉树加入到F 中; (4) 重复(2)、(3)两步,当集合F 中只剩下一棵二叉树时,这棵二叉树便是哈夫曼树. 2.2存储结构 在由哈夫曼算法构造的哈夫曼树中,非叶子结点的度均为2,根据二叉树的性质可知,具有n 个叶子结点的哈夫曼树共有2n-1个结点,其中有n-1个非叶子结点,它们是在n-1次的合并过程中生成的.为了便于选取根结点权值最小的二叉树以及合并操作,设置一个数组HuffmanNode[2n-1]保存哈夫曼树中各结点的信息,数组元素的结点结构如图所示. 图 哈夫曼树的结点结构 其中: weight parent lchild rchild i nf

数字图像实验 哈夫曼编码的方法和实现1234

实验八哈夫曼编码的方法和实现 一、实验目的 1.掌握哈夫曼编码的基本理论和算法流程; 2. 用VC++6.0编程实现图像的哈夫曼编码。 二、实验内容 1.画出哈夫曼编码的算法流程; 2.用VC++6.0编程实现哈夫曼编码。 三、实验步骤 (1)启动VC++6.0,打开Dip工程。 (2)在菜单栏→insert→resouce→dialog→new,在对话框模版的非控制区点击鼠标右键,在弹出的对话框中选properties,设置为ID:IDD_DLG_Huffman,C标题:哈夫曼编码表。 (3)在弹出的对话框中,添加如下的按钮等控件: (4)在ResourceView栏中→Menu→选IDR_DIPTYPE ,如图 在图像编码菜单栏下空的一栏中,右键鼠标,

在弹出的对话框中选属性properties,在弹出的对话框中,进行如下的设置 (5)右击哈夫曼编码表菜单栏,在建立的类向导中进行如下设置 (6)在DipDoc.cpp中找到void CDipDoc::OnCodeHuffman()添加如下代码void CDipDoc::OnCodeHuffman() { int imgSize; imgSize = m_pDibObject->GetWidth()*m_pDibObject->GetHeight(); //在点处理CPointPro类中创建用来绘制直方图的数据 CPointPro PointOperation(m_pDibObject ); int *pHistogram = PointOperation.GetHistogram(); //生成一个对话框CHistDlg类的实例 CDlgHuffman HuffmanDlg;

哈夫曼编码课程设计

湖南科技学院 课程设计报告 课程名称:数据结构课程设计 课程设计题目:哈夫曼编码 系:数学与计算科学系 专业:信息与计算科学 年级、班:信计0901 姓名:郭如华 学号:200905002145 指导教师:牛志毅 职称:讲师 2011年12月

目录 1 问题描述 (3) 2 基本要求 (3) 3 测试数据 (3) 4 算法思想 (3) 5 模块划分 (3) 6 数据结构 (3) 7 源程序 (4) 8 测试情况 (9) 9 设计总结 (9) 10参考资料 (9)

1 问题描述 设计一个哈夫曼编码系统,对文档中的报文进行编码,输出这段报文的哈夫曼编码,并且可以对输入的哈夫曼编码进行译码。 2 基本要求 从文档中读取报文(如"what did you do that made you so happy")进行编码输出这段报文的哈夫曼编码。 3 测试数据 what did you do that made you so happy 4算法思想 ①:从文件中读取lei.txt并到数组z(保存所有字符的种类),读取data,txt存到数组ch(保存统计频数的一个样本)。 ②:对数组z和数组ch进行比较统计出每个字符出现的频数,以频数代替权值,并把权值赋值到ht.weight的的数组中。 ③:利用权值创建哈夫曼树。 ④:利用哈夫曼树求的哈夫曼编码。把lei.txt的数据赋值到hcd.ch中,把编好的哈夫曼编码赋值到hcd.code,则hcd这个数组就是一个哈夫曼编码的集合,hcd.ch 对应的下标就是这个字符所对应的哈夫曼编码。 ⑤:输入要编码的字符,保存到ch数组,把ch数组的ch[j]元素逐个与hcd[i].ch 比较找出下标i,则hcd[i].code为ch[j]元素的哈夫曼编码。 ⑥:输入要译码的哈夫曼编码lcd,逐个与hcd[i].code比较,找出下标i,则hcd[i].ch 为lcd所对应的字符。 5 模块划分 ①:void inithuffmantree(huffmantree ht);/*初始化哈夫曼树*/ ②:void tongji(huffmantree ht,huffmancode hcd,char *ch,char *z);/*统计权值*/ ③:void selectmin(huffmantree ht, int i, int *p1, int *p2);/*选择最小的权值*/ ④:void createhuffmantree(huffmantree ht) ;/*创建哈夫曼树*/ ⑤:void huffmancodes(huffmantree ht,huffmancode hcd,char *z) ;/*利用哈夫曼树求哈夫曼编码*/ ⑥:void bianma(huffmancode hcd);/*对输入的字符进行编码*/ ⑦:void yima(huffmancode hcd);/*对输入的哈夫曼编码进行译码*/ 6 数据结构 typedef struct { int weight; int lchild,rchild,parent; }htnode; typedef htnode huffmantree[m+1];定义哈夫曼树的结构类型。

哈夫曼编码的方法

1.哈夫曼编码的方法 编码过程如下: (1) 将信源符号按概率递减顺序排列; (2) 把两个最小的概率加起来, 作为新符号的概率; (3) 重复步骤(1) 、(2), 直到概率和达到1 为止; (4) 在每次合并消息时,将被合并的消息赋以1和0或0和1; (5) 寻找从每个信源符号到概率为1处的路径,记录下路径上的1和0; (6) 对每个符号写出"1"、"0"序列(从码数的根到终节点)。 2.哈夫曼编码的特点 ①哈夫曼方法构造出来的码不是唯一的。 原因 ·在给两个分支赋值时, 可以是左支( 或上支) 为0, 也可以是右支( 或下支) 为0, 造成编码的不唯一。 ·当两个消息的概率相等时, 谁前谁后也是随机的, 构造出来的码字就不是唯一的。 ②哈夫曼编码码字字长参差不齐, 因此硬件实现起来不大方便。 ③哈夫曼编码对不同的信源的编码效率是不同的。 ·当信源概率是2 的负幂时, 哈夫曼码的编码效率达到100%; ·当信源概率相等时, 其编码效率最低。 ·只有在概率分布很不均匀时, 哈夫曼编码才会收到显著的效果, 而在信源分布均匀的情况下, 一般不使用哈夫曼编码。 ④对信源进行哈夫曼编码后, 形成了一个哈夫曼编码表。解码时, 必须参照这一哈夫编码表才能正确译码。 ·在信源的存储与传输过程中必须首先存储或传输这一哈夫曼编码表在实际计算压缩效果时, 必须考虑哈夫曼编码表占有的比特数。在某些应用场合, 信源概率服从于某一分布或存在一定规律

使用缺省的哈夫曼编码表有

解:为了进行哈夫曼编码, 先把这组数据由大到小排列, 再按上方法处理 (1)将信源符号按概率递减顺序排列。 (2)首先将概率最小的两个符号的概率相加,合成一个新的数值。 (3)把合成的数值看成是一个新的组合符号概率,重复上述操作,直到剩下最后两个符号。 5.4.2 Shannon-Famo编码 Shannon-Famo(S-F) 编码方法与Huffman 的编码方法略有区别, 但有时也能编 出最佳码。 1.S-F码主要准则 符合即时码条件; 在码字中,1 和0 是独立的, 而且是( 或差不多是)等概率的。 这样的准则一方面能保证无需用间隔区分码字,同时又保证每一位码字几乎有 1位的信息量。 2.S-F码的编码过程 信源符号按概率递减顺序排列; 把符号集分成两个子集, 每个子集的概率和相等或近似相等;

相关主题