完整word版Huffman编码报告.docx

上传人:b****5 文档编号:3916043 上传时间:2022-11-26 格式:DOCX 页数:31 大小:169.18KB
下载 相关 举报
完整word版Huffman编码报告.docx_第1页
第1页 / 共31页
完整word版Huffman编码报告.docx_第2页
第2页 / 共31页
完整word版Huffman编码报告.docx_第3页
第3页 / 共31页
完整word版Huffman编码报告.docx_第4页
第4页 / 共31页
完整word版Huffman编码报告.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

完整word版Huffman编码报告.docx

《完整word版Huffman编码报告.docx》由会员分享,可在线阅读,更多相关《完整word版Huffman编码报告.docx(31页珍藏版)》请在冰豆网上搜索。

完整word版Huffman编码报告.docx

完整word版Huffman编码报告

《数据结构》课程设计上机实习报告

 

课设题目

Huffman编码和解码

班级

学生姓名

学号

指导教师

时间

2015.12—2015。

1

一、设计目的

1.进一步熟悉C语言开发环境,熟悉用C语言完成一个应用程序的设计过程,掌握有关编辑、调试和整合程序的方法和技巧.

2.通过此设计,了解《数据结构》课程中霍夫曼编码的的有关内容,明确其操作,熟悉其设计,同时学习到有关位向量的内容,对文件掌握加深

二、设计内容

Huffman编码与解码(必做)(Huffman编码、二叉树)

[问题描述]

对一篇英文文章(大于2000个英文字符),统计各字符出现的次数,实现Huffman编码,以及对编码结果的解码.

[基本要求]

(1)输出每个字符出现的次数和编码,其中求最小权值要求用堆实现。

(2)在Huffman编码后,要将编码表和英文文章编码结果保存到文件中,编码结果必须是二进制形式,即01的信息用比特位表示,不能用字符’0’和'1’表示.

(3)提供读编码文件生成原文件的功能。

三、数据结构说明

在该程序中我仅仅使用了两个结构体来完成编码,用位域来实现bite流存储:

constintMAXSIZE=300;//定义一次分配的Huffman储存单词最大量为500

constintOVERFLOW=0;

constintERROR=0;

constintLineCountNum=500;

typedefstructWordCount

charWord;//存放字符

intfreq;

intparent,lchild,rchild;//存放亲子节点位置

intplace;//用来保存第一次堆排序后,建立霍夫曼表前的相对位置

char*HuffmanCode;//存放霍夫曼编码

}WordCount,*WC;//存放单词结点的结构体

typedefstructHuffmanTree

{

WCw;

intNumber;//存储有多少数据存入

}HuffmanTree,*HTree;

typedefstruct

unsignedinta:

1;

}bite;//设置位段,存储一个bite

//**************操作函数声明***********

voidInitHuffmanTree(HTree&H);//初始化霍夫曼树

voidHeapSort(WC&W,intNumber,intchoice);//堆排序核心函数

voidHeapAdjust(WC&W,intdown,intup,intchoice);//堆排序调整函数,实现两种排序

voidHuffmanCoding(HTree&H,WC&HT);//求霍夫曼树和霍夫曼编码表

voidShowHuffmanTree(HTreeH);//输出霍夫曼树

voidSelect(WC&W,inti,int&s1,int&s2);//选择1-i—1之间最小的两个数,且parent为0,用s1,s2返回

voidGetTheDeCode(HTreeH);//将编码结果写入函数

voidPutTheDeCode(FILE*fp1,FILE*fp2);//将编码结果解码得到文章

voidCountTheWord(HTree&H,FILE*fp);//记录单词权值

voidShowTheEassy(FILE*wp);//展示文章

四、详细设计

1.首先我给出了编码和解码的菜单供其选择

2.在编码功能中,我先通过CountTheWord()函数进行单词权值记录,然后进入编码功能,值得一提的是,编码时我给堆排序设计了两种排序形式—-对权值的排序和对位置的排序,以达到选择两个最小的权值结点的最优时间复杂度的目的,此功能通过switch实现,但要给编码结构体中放置一个place空间,这也从侧面反映了时间和空间矛盾的地方(值得一提的是,有些编码并不可见且有特殊含义,如换行符,所以将字符放入文件中时,并不对其进行处理,读出是进行顺序读出)

3.编码结束后将编码结果,对应字符分别存放在文件中,然后对整篇文章进行编码

4.解码时依据霍夫曼编码的唯一性进行比较求解,遇到同样的字符即返回对应的字母并写入解码文件中

五、调试与测试(测试数据:

献给艾米莉的玫瑰)

1.首先打开文件进行字符权值统计并输出结果(有些符号不可见,所以无法显示)

2.然后对其进行堆排序

3.输出编码表,及其对应亲子关系(#号代表为父结点)

4.输出编码结果(可以轻易看出编码具备唯一性)

5.将编码写入文件,一下显示文件部分内容

位域存储的bite编码文档

编码对应的字符顺序存储(可以看到因为换行符的存在,自动换行了)

6.解码(将文章在命令行显示,也写入了翻译文档(以doc格式保存))

六、课程设计总结

本次程序设计过程中遇到过许多大大小小的问题,也在设计思路上遇到过难题,但都在各方面的努力下得到了解决。

一些问题如下:

1.Bite形式保存

由于以前没学到过位向量的内容,有一段时间无法实现这个功能,后来在网络上偶然接触到位域的内容,认识到其可行性,于是解决了此问题

2.选择最小的两个权值

一开始我认识的这个可能很复杂,又联想到堆排序可以对其有序输出,但我又不想改变其位置,所以增设一个place记录一开始的编码表位置,进行编码时改变后可以轻易还原

总结:

霍夫曼编码在通信领域内是十分重要的内容,对其的掌握既能帮助我们理解二叉树的重要性,也能为我们未来工作提供一个更广阔的舞台

七、附录

/*

*题目:

Huffman编码的编码和解码

*作者:

杨欢

*学号:

161420325

*完成时间:

2015-12-30

算法思想:

以书上的霍夫曼算法为核心进行文章(所有内容,包括标点,换行符,所以命令行可能无法显示部分字符)编码和解码.

对于比特位的存储,我选择用位域进行简单方便的操作。

文件的读写都以最基本的方式进行.

测试文章上,我选择艾米莉的玫瑰这一小说测试,数据量大,可以验证程序的正确性

*/

#include〈stdio。

h>

#include〈stdlib.h〉

#include〈string。

h〉

constintMAXSIZE=300;//定义一次分配的Huffman储存单词最大量为500

constintOVERFLOW=0;

constintERROR=0;

constintLineCountNum=500;

typedefstructWordCount

{

charWord;//存放字符

intfreq;

intparent,lchild,rchild;//存放亲子节点位置

intplace;//用来保存第一次堆排序后,建立霍夫曼表前的相对位置

char*HuffmanCode;//存放霍夫曼编码

}WordCount,*WC;//存放单词结点的结构体

typedefstructHuffmanTree

WCw;

intNumber;//存储有多少数据存入

}HuffmanTree,*HTree;

typedefstruct

{

unsignedinta:

1;

}bite;//设置位段,存储一个bite

//**************操作函数声明***********

voidInitHuffmanTree(HTree&H);//初始化霍夫曼树

voidHeapSort(WC&W,intNumber,intchoice);//堆排序核心函数

voidHeapAdjust(WC&W,intdown,intup,intchoice);//堆排序调整函数,实现两种排序

voidHuffmanCoding(HTree&H,WC&HT);//求霍夫曼树和霍夫曼编码表

voidShowHuffmanTree(HTreeH);//输出霍夫曼树

voidSelect(WC&W,inti,int&s1,int&s2);//选择1—i—1之间最小的两个数,且parent为0,用s1,s2返回

voidGetTheDeCode(HTreeH);//将编码结果写入函数

voidPutTheDeCode(FILE*fp1,FILE*fp2);//将编码结果解码得到文章

voidCountTheWord(HTree&H,FILE*fp);//记录单词权值

voidShowTheEassy(FILE*wp);//展示文章

//************主函数***************

intmain()

FILE*fp,*wp;

HTreeH;

WCHT;//存放编码表

printf("*************菜单**************************\n");

printf("*********1.编码文档********\n");

printf(”*********2.解码文档********\n");

printf(”*********0.退出****************************\n”);

printf(”请输入您的选择:

");

intchoice;

scanf("%d",&choice);

getchar();

while(choice!

=0)

{

switch(choice)

case1:

InitHuffmanTree(H);

if(!

(fp=fopen("献给艾米莉的玫瑰。

txt”,"r”)))

{//以文本文件形式打开文件

printf("此文件不存在\n”);

exit(ERROR);

}

printf("文件打开成功\n”);

CountTheWord(H,fp);

printf(”按任意键统计该文章各字符出现的频率为\n");

getchar();

ShowHuffmanTree(H);

printf("按任意键开始堆排序\n”);

getchar();

HeapSort(H-〉w,H—>Number,1);//对频率排序

printf(”按任意键输出堆排序后的情况\n”);

getchar();

ShowHuffmanTree(H);

printf(”现在开始进行霍夫曼树的构建和霍夫曼编码的构建\n");

HuffmanCoding(H,HT);

printf(”输入任意键输出霍夫曼编码表:

");

getchar();

printf(”字符位置权值左孩子右孩子父亲\n");

for(inti=1;i〈=2*H—>Number;++i)

printf("%c%d%d%d%d%d\n",HT[i]。

Word,i,HT[i].freq,HT[i]。

lchild,HT[i].rchild,HT[i]。

parent);

printf("按任意键输出构建的霍夫曼编码结果:

”);

getchar();

for(inti=1;i<=H—>Number;++i)

{

printf("%c对应的编码为%s\n”,H—>w[i].Word,H—>w[i].HuffmanCode);

printf("按任意键将结果写入文件\n");

getchar();

GetTheDeCode(H);

free(H);//释放空间,避免影响

break;

case2:

PutTheDeCode(fp,wp);

printf("该英文文章为\n");

ShowTheEassy(wp);

printf("\n");

fclose(fp);

break;

case0:

break;

printf(”请输入您的选择:

");

scanf("%d”,&choice);

getchar();

return0;

}

//*********操作函数实现**********

voidInitHuffmanTree(HTree&H)

if(!

(H=(HuffmanTree*)malloc(sizeof(HuffmanTree))))

exit(OVERFLOW);

if(!

(H-〉w=(WC)malloc(sizeof(WordCount)*MAXSIZE)))

exit(OVERFLOW);//创建结点

H—>Number=0;

}

//****************将结果写入文件********************

voidGetTheDeCode(HTreeH)

FILE*fp,*wp;

//********将编码表写出********

if(!

(fp=fopen(”编码表文档.txt","w”)))

{//以二进制方式写出文章编码

printf(”此文件不存在\n”);

clearerr(fp);

exit(ERROR);

for(inti=1;i〈=H—〉Number;++i)

fprintf(fp,"%s\n”,H—>w[i]。

HuffmanCode);

fclose(fp);

if(!

(fp=fopen(”编码表对应单词文档.txt",”w")))

{//以二进制方式写出文章编码

printf(”此文件不存在\n”);

clearerr(fp);

exit(ERROR);

}

for(inti=1;i〈=H-〉Number;++i)

fprintf(fp,"%c",H->w[i].Word);//因为存在换行符,需要进行读取换行符,所以不进行分行存储

fclose(fp);

//********将编码文档写出***********

if(!

(fp=fopen("献给艾米莉的玫瑰.txt",”r")))

{//打开文章进行对比写出编码结果

printf("此文件不存在\n”);

clearerr(fp);

exit(ERROR);

if(!

(wp=fopen(”编码文档.txt",”wb")))

{//以二进制形式写出编码文档

printf(”此文档不存在\n”);

clearerr(wp);

exit(ERROR);

biteSave;

while(!

feof(fp))

charCount;

fscanf(fp,”%c",&Count);

for(inti=1;i<=H—〉Number;++i)

if(Count==H->w[i]。

Word)

{//寻找到匹配的,得到其字符编码,现在将其以Bite位写出到文件

for(intj=0;j

{

if(H—〉w[i]。

HuffmanCode[j]==’1')

Save.a=1;

else

Save.a=0;

fwrite(&Save,sizeof(bite),1,wp);//用位段写进文件

}

break;

}

}

fclose(fp);

fclose(wp);

printf(”写出成功\n”);

}

//***********将编码文件翻译成英文************

voidPutTheDeCode(FILE*fp,FILE*wp)

HTreeH;

InitHuffmanTree(H);

//*************读取编码文件********

if(!

(fp=fopen(”编码表文档.txt”,”r")))

{

printf("此文件不存在\n”);

clearerr(fp);

exit(ERROR);

}

intNum=1;

charCount[MAXSIZE];//存放出来的01字符串

memset(Count,0,MAXSIZE*sizeof(char));

while(!

feof(fp))

{

fscanf(fp,"%s",Count);

if(strlen(Count)!

=0)

if(!

(H-〉w[Num].HuffmanCode=(char*)malloc((strlen(Count)+1)*sizeof(char))))

exit(OVERFLOW);

strcpy(H—〉w[Num].HuffmanCode,Count);

memset(Count,0,strlen(Count)*sizeof(char));//清零

++Num;

}//将编码导出

fclose(fp);

if(!

(fp=fopen(”编码表对应单词文档。

txt”,"r”)))

{

printf("此文件不存在\n”);

clearerr(fp);

exit(ERROR);

}

Num=1;

while(!

feof(fp))

H—>w[Num]。

Word=fgetc(fp);

++Num;

}

fclose(fp);

//**************翻译**********

if(!

(fp=fopen("编码文档。

txt”,"rb”)))

{//以二进制读取编码文档

printf(”此文件不存在\n”);

clearerr(fp);

exit(ERROR);

}

if(!

(wp=fopen("翻译文档。

doc”,"w”)))

{//写出文章编码

printf(”此文件不存在\n”);

clearerr(wp);

exit(ERROR);

bitePut;//位段,用来将字符读出

Num=Num—2;//存储了多余的换行符并且多加了一次,还原真实数目

intNumberCount=strlen(H->w[Num]。

HuffmanCode);//存放最小的霍夫曼编码数,减小后面的比较次数

intCT,i=0,j=1;

while(!

feof(fp))

if(i

{//从最小字符串开始可以减少循环

fread(&Put,sizeof(bite),1,fp);

if(Put.a==1)

Count[i]=’1’;

else

Count[i]=’0';

++i;

else

while(j<=Num)

if(strcmp(Count,H—〉w[j]。

HuffmanCode)==0)

{//依据霍夫曼编码的唯一性,遇到编码相同即可进行单词写入

fprintf(wp,"%c”,H—〉w[j]。

Word);

//编码匹配,清空计数和数组,状态重置

memset(Count,0,sizeof(char)*(i+1));

i=0;

j=1;

break;

++j;

if(j>Num)

{//代表当前编码不是霍夫曼编码,继续读入编码

fread(&Put,sizeof(bite),1,fp);

if(Put。

a==1)

Count[i]=’1';

else

Count[i]=’0’;

j=1;

++i;

}

fclose(fp);

fclose(wp);

//**************解码文章输出**********

voidShowTheEassy(FILE*wp)

if(!

(wp=fopen("翻译文档。

doc","r")))

{//写出文章编码

printf("此文件不存在\n");

clearerr(wp);

exit(ERROR);

charLine[LineCountNum];

while(!

feof(wp))

{

fgets(Line,LineCountNum,wp);

printf("%s",Line);

memset(Line,0,sizeof(char)*strlen(Line));//清零

}

//***********存储单词***************

voidCountTheWord(HTree&H,FILE*fp)

intWordNumCount=1;//单词结点记载

intjcount;//单词重复比较操作时的临时变量

charLineCount[LineCountNum];//读入文章时规定一行最

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

当前位置:首页 > 人文社科 > 设计艺术

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1