哈弗曼编码实验报告.docx

上传人:b****5 文档编号:7453975 上传时间:2023-05-11 格式:DOCX 页数:17 大小:19.78KB
下载 相关 举报
哈弗曼编码实验报告.docx_第1页
第1页 / 共17页
哈弗曼编码实验报告.docx_第2页
第2页 / 共17页
哈弗曼编码实验报告.docx_第3页
第3页 / 共17页
哈弗曼编码实验报告.docx_第4页
第4页 / 共17页
哈弗曼编码实验报告.docx_第5页
第5页 / 共17页
哈弗曼编码实验报告.docx_第6页
第6页 / 共17页
哈弗曼编码实验报告.docx_第7页
第7页 / 共17页
哈弗曼编码实验报告.docx_第8页
第8页 / 共17页
哈弗曼编码实验报告.docx_第9页
第9页 / 共17页
哈弗曼编码实验报告.docx_第10页
第10页 / 共17页
哈弗曼编码实验报告.docx_第11页
第11页 / 共17页
哈弗曼编码实验报告.docx_第12页
第12页 / 共17页
哈弗曼编码实验报告.docx_第13页
第13页 / 共17页
哈弗曼编码实验报告.docx_第14页
第14页 / 共17页
哈弗曼编码实验报告.docx_第15页
第15页 / 共17页
哈弗曼编码实验报告.docx_第16页
第16页 / 共17页
哈弗曼编码实验报告.docx_第17页
第17页 / 共17页
亲,该文档总共17页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

哈弗曼编码实验报告.docx

《哈弗曼编码实验报告.docx》由会员分享,可在线阅读,更多相关《哈弗曼编码实验报告.docx(17页珍藏版)》请在冰点文库上搜索。

哈弗曼编码实验报告.docx

哈弗曼编码实验报告

一.实验目的

1、掌握哈夫曼树的构造和应用

2、利用哈夫曼方法及其编/译码技术实现对传输信息编码/译码系统.

二.实验内容

1、哈夫编码/译码器简介

本例说明,先前快速远距离通信的主要手段是电报,即将需传送的文字转换成由二进制的字符组成的字符串。

在传送电文时,希望总长尽可能地短,如果对每个字符设计长度不等的编码,且让电文中出现次数较多的字符采用尽可能短的编码,以减少经费。

哈夫曼树就是根据此原理设计出来的一种存储结构。

2、问题描述

哈夫曼树很易求出给定字符集及其概率(或频度)分布的最优前缀码。

哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。

该技术一般可将数据文件压缩掉20%至90%,其压缩效率取决于被压缩文件的特征。

利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时,降低传输成本。

但是,这要求在发送端通过一个编码系统对待传送电文须预先编码,在接收须将传送来的数据进行译码。

请自行设计实现一个具有初始化、编码、译码、输入/输出等功能的哈夫曼码的编码/译码系统。

并实现以下报文的编码和译码:

“thisprogramismyfavorite”。

3.测试数据

某通信的电文字符集为26个英文字母及空格字符,其出现频度如下表所示:

4、设计思想描述

(1)问题分析。

(2)哈夫曼树中各结点的结构描述(如上图)。

(3)哈夫曼树的存储结构描述。

5、主要算法设计与实现

(1)哈弗曼树的定义(动态分配数组存储哈夫曼树)

typedefstruct{

charch;//键值

intweight;//权值

intselected;//编码值

intparent,lchild,rchild;//各节点的值

}HTNode,*HuffmanTree;//动态分配数组存储哈夫曼树

(2)定义用于译码的树

typedefstructTreeNode{

structTreeNode*lchild;//结构指针

structTreeNode*rchild;

charcode;

chardata;

}TreeNode,*Tree;

(3)哈夫曼树函数的设计

voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*&w,intn){//建立哈弗曼树

intm=2*n-1,i,j,s1,s2,start,f;

char*cd;

HuffmanTreep;

if(n<=1)return;

HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未使用

for(p=HT+1,i=1;i<=n;i++,p++,w++){

p->weight=*(w+1);

p->selected=p->lchild=p->rchild=p->parent=0;

}

for(;i<=m;i++,p++)

p->selected=p->parent=p->lchild=p->rchild=0;

for(i=n+1;i<=m;i++){//建立哈弗曼树

Select(HT,i-1,&s1,&s2);

HT[s1].parent=i;

HT[s2].parent=i;

HT[i].lchild=s1;

HT[i].rchild=s2;

HT[i].weight=HT[s1].weight+HT[s2].weight;

}

printf("\n哈弗曼树表\n");//打印哈弗曼树表

printf("iweightparentlchildrchild\n");

for(p=HT+1,i=1;i<=m;i++,p++)

printf("%2d%6d%6d%6d%6d\n",i,p->weight,p->parent,p->lchild,p->rchild);

printf("\n");

//从叶子到根逆向求每个字符的哈夫曼编码

HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n个字符编码的头指针向量

cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空间

cd[n-1]='\0';//编码结束符

for(i=1;i<=n;i++){//逐个字符求哈夫曼编码

start=n-1;//编码结束位置for(j=i,f=HT[i].parent;f!

=0;j=f,f=HT[f].parent){//从叶子到根逆向求编码

if(HT[f].lchild==j)

cd[--start]='0';

else

cd[--start]='1';

}

HC[i]=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间

strcpy(HC[i],&cd[start]);//从cd复制编码到HC

}

free(cd);//释放工作空间

}

(4)对编码函数的设计

voidCodeInput(intn,int*&w,char*&code){//字符及权值的输入

inti;

w=(int*)malloc((n+1)*sizeof(int));//分配权值的工作空间

code=(char*)malloc((n+1)*sizeof(char));//分配字符的工作空间

printf("请输入字符以及权值:

\n");

for(i=1;i<=n;i++){

fflush(stdin);//清除缓从区间

scanf("%c%d",&code[i],&w[i]);

}

}

voidEncoding(Sentence&sentence,char*&code,HuffmanCode&HC,intn){//編码

charc,t,*pp;

inti;

Sentencep,q;

sentence=(Sentence)malloc(sizeof(S));

q=sentence;

q->next=NULL;

printf("请输入待编码的字符串:

\n");

fflush(stdin);

while(scanf("%c",&c)!

=EOF&&c!

='\n'){

for(i=1;i<=n;i++){

t=code[i];

if(c==t){

pp=HC[i];

break;

}

}

for(i=0;pp[i]!

='\0';i++){

p=(Sentence)malloc(sizeof(S));

p->c=pp[i];

q->next=p;

p->next=NULL;

q=p;

}

}

p=sentence->next;

printf("\n编码后的语句:

\n");

while(p!

=NULL){

printf("%c",p->c);

p=p->next;

}

printf("\n");

}

(5)对译码函数的设计

voidDecoding(Sentence&sentence,char*&code,HuffmanCode&HC,Tree&root,intn){//译码

Treep,q;

Sentencer=sentence->next;

inti,j;

charc,*t;

root=(Tree)malloc(sizeof(TreeNode));

root->lchild=NULL;

root->rchild=NULL;

for(i=1;i<=n;i++){

t=HC[i];

q=root;

for(j=0;j

c=t[j];

if(q->lchild!

=NULL){

if(q->lchild->code==c){

q=q->lchild;

}

elseif(q->rchild!

=NULL){

q=q->rchild;

}

else{

p=(Tree)malloc(sizeof(TreeNode));

p->lchild=NULL;

p->rchild=NULL;

p->code=c;

if(t[j+1]!

='\0')

p->data='n';

else

p->data=code[i];

q->rchild=p;

q=p;

}

}

else{

p=(Tree)malloc(sizeof(TreeNode));

p->lchild=NULL;

p->rchild=NULL;

p->code=c;

if(t[j+1]!

='\0')

p->data='n';

else

p->data=code[i];

q->lchild=p;

q=p;

}

}

}

q=root;

printf("\n解码后的语句:

\n");

while(r!

=NULL){

c=r->c;

if(q->lchild!

=NULL){

if(q->lchild->code==c){

q=q->lchild;

if(q->lchild==NULL){

printf("%c",q->data);

q=root;

}

}

else{

q=q->rchild;

if(q->lchild==NULL){

printf("%c",q->data);

q=root;

}

}

}

else{

printf("%c",q->data);

q=root;

}

r=r->next;

}

printf("\n\n");

return;}

三实验结果

根据此次实验的设计,我们编写出相应的源代码,在运行时可以得到相应的功能:

其运行界面如下图所示:

在上面输入所需输入字符集大小。

如输入26个英文字母及空格时

所得的哈弗曼树(如下图部分)及哈弗曼编码(如下图部分)

当输入带编码语句“thisprogrameismyfavorite”时,按回车,出现其编码后的语句及译码后的语句如下图:

四实验总结

通过本次数据结构的课程设计,我学习了很读我之前上课没懂的知识。

并在老师指导下,我对求哈夫曼树及哈夫曼编码/译码的算法有了更加深刻的了解,更巩固了课堂中学习有关于哈夫曼编码的知识,真正学会一种算法了。

当求解一个算法时,不是拿到问题就不加思索地做,而是首先要先对它有个大概的了解,接着再详细地分析每一步怎么做,无论自己以前是否有处理过相似的问题,只要按照以上的步骤,必定会顺利地做出来。

这次课程设计中我在编辑中犯了不应有的错误,设计统计字符和合并时忘记应该怎样保存保存数据,在老师的指导下改正了错误和疏漏,使我们的程序有了更高的质量。

有时还是会遇到一些这样或那样的问题,在这时就要看团体的力量,遇到困难时我们组会聚集到一块儿合力讨论,尽力把它解决,每次解决了一个问题之后就会给自己多了一份自信,对今后的学习和程序的设计有了更大的信心。

再次我真心的感谢老师对我们的帮助与指导。

我会更加努力学习数据结构方面的知识,来完善自己的学习。

五代码

#include

#include

#include

typedefstruct{

charch;

intweight;

intselected;

intparent,lchild,rchild;

}HTNode,*HuffmanTree;//动态分配数组存储哈夫曼树

typedefstructS{

charc;

structS*next;

}S,*Sentence;//用于待编码的语句

typedefchar**HuffmanCode;//动态分配数组存储哈夫曼编码表

typedefstructTreeNode{

structTreeNode*lchild;

structTreeNode*rchild;

charcode;

chardata;

}TreeNode,*Tree;//用于解码的树

voidSelect(HuffmanTree&HT,intposition,int*s1,int*s2){//选择函数

inti,j,t;

intp,q;

intfirst,second;

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

if(HT[i].selected==0){

first=HT[i].weight;

break;

}

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

if(HT[j].selected==0){

second=HT[j].weight;

break;

}

if(first>second){

t=first;

first=second;

second=t;

}

for(i=j+1;i<=position;i++){

if(HT[i].selected==0){

t=HT[i].weight;

if(t

second=first;

first=t;

}

elseif(t

second=t;

}

}

}

for(i=1;i<=position;i++){

if(HT[i].selected==0&&HT[i].weight==first){

HT[i].selected=1;

p=i;

break;

}

}

for(i=1;i<=position;i++){

if(HT[i].selected==0&&HT[i].weight==second){

HT[i].selected=1;

q=i;

break;

}

}

if(p>q){

t=q;

q=p;

p=t;

}

*s1=p;

*s2=q;

return;

}

voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*&w,intn){//建立哈弗曼树

intm=2*n-1,i,j,s1,s2,start,f;

char*cd;

HuffmanTreep;

if(n<=1)

return;

HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未使用

for(p=HT+1,i=1;i<=n;i++,p++,w++){

p->weight=*(w+1);

p->selected=p->lchild=p->rchild=p->parent=0;

}

for(;i<=m;i++,p++)

p->selected=p->parent=p->lchild=p->rchild=0;

for(i=n+1;i<=m;i++){//建立哈弗曼树

Select(HT,i-1,&s1,&s2);

HT[s1].parent=i;

HT[s2].parent=i;

HT[i].lchild=s1;

HT[i].rchild=s2;

HT[i].weight=HT[s1].weight+HT[s2].weight;

}

printf("\n哈弗曼树表\n");//打印哈弗曼树表

printf("iweightparentlchildrchild\n");

for(p=HT+1,i=1;i<=m;i++,p++)

printf("%2d%6d%6d%6d%6d\n",i,p->weight,p->parent,p->lchild,p->rchild);

printf("\n");

//从叶子到根逆向求每个字符的哈夫曼编码

HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n个字符编码的头指针向量

cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空间

cd[n-1]='\0';//编码结束符

for(i=1;i<=n;i++){//逐个字符求哈夫曼编码

start=n-1;//编码结束位置

for(j=i,f=HT[i].parent;f!

=0;j=f,f=HT[f].parent){//从叶子到根逆向求编码

if(HT[f].lchild==j)

cd[--start]='0';

else

cd[--start]='1';

}

HC[i]=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间

strcpy(HC[i],&cd[start]);//从cd复制编码到HC

}

free(cd);//释放工作空间

}

voidCodeInput(intn,int*&w,char*&code){//字符及权值的输入

inti;

w=(int*)malloc((n+1)*sizeof(int));//分配权值的工作空间

code=(char*)malloc((n+1)*sizeof(char));//分配字符的工作空间

printf("请输入字符以及权值:

\n");

for(i=1;i<=n;i++){

fflush(stdin);//清除缓从区间

scanf("%c%d",&code[i],&w[i]);

}

}

voidEncoding(Sentence&sentence,char*&code,HuffmanCode&HC,intn){//编码

charc,t,*pp;

inti;

Sentencep,q;

sentence=(Sentence)malloc(sizeof(S));

q=sentence;

q->next=NULL;

printf("请输入待编码的字符串:

\n");

fflush(stdin);

while(scanf("%c",&c)!

=EOF&&c!

='\n'){

for(i=1;i<=n;i++){

t=code[i];

if(c==t){

pp=HC[i];

break;

}

}

for(i=0;pp[i]!

='\0';i++){

p=(Sentence)malloc(sizeof(S));

p->c=pp[i];

q->next=p;

p->next=NULL;

q=p;

}

}

p=sentence->next;

printf("\n编码后的语句:

\n");

while(p!

=NULL){

printf("%c",p->c);

p=p->next;

}

printf("\n");

}

voidDecoding(Sentence&sentence,char*&code,HuffmanCode&HC,Tree&root,intn){//解码

Treep,q;

Sentencer=sentence->next;

inti,j;

charc,*t;

root=(Tree)malloc(sizeof(TreeNode));

root->lchild=NULL;

root->rchild=NULL;

for(i=1;i<=n;i++){

t=HC[i];

q=root;

for(j=0;j

c=t[j];

if(q->lchild!

=NULL){

if(q->lchild->code==c){

q=q->lchild;

}

elseif(q->rchild!

=NULL){

q=q->rchild;

}

else{

p=(Tree)malloc(sizeof(TreeNode));

p->lchild=NULL;

p->rchild=NULL;

p->code=c;

if(t[j+1]!

='\0')

p->data='n';

else

p->data=code[i];

q->rchild=p;

q=p;

}

}

else{

p=(Tree)malloc(sizeof(TreeNode));

p->lchild=NULL;

p->rchild=NULL;

p->code=c;

if(t[j+1]!

='\0')

p->data='n';

else

p->data=code[i];

q->lchild=p;

q=p;

}

}

}

q=root;

printf("\n解码后的语句:

\n");

while(r!

=NULL){

c=r->c;

if(q->lchild!

=NULL){

if(q->lchild->code==c){

q=q->lchild;

if(q->lchild==NULL){

printf("%c",q->data);

q=root;

}

}

else{

q=q->rchild;

if(q->lchild==NULL){

printf("%c",q->data);

q=root;

}

}

}

else{

printf("%c",q->data);

q=root;

}

r=r->next;

}

printf("\n\n");

return;

}

intmain(void){//主函数

HuffmanTreeHT;

HuffmanCodeHC;

Treeroot;

int*w,n,i;

char*code;

printf("\t\t设字符集为26个英文字母,其出现频度如下表所示:

\n");

printf("\t\t******************************************\n");

printf("\t\t字符|空格|a|b|c|d|e|f|g|h|\n");

printf("\t\t频度|186|64|13|22|32|103|21|15|47|\n");printf("\n");

printf("\t\t字符|i|j|k|l|m|n|o|p|q|\n");

printf("\t\t频度|57|1|5|32|20|57|63|15|1|\n");printf("\n");

printf("\t\t字符|r|s|t|u|v|w|x|y|z|\n");

printf("\t\t频度|48|51|80|23|8|18|1|16|1|\n");

printf("\t\t******************************************\n");

printf("请输入字符集大小n(整型):

\n");

scanf(

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2