Huffman编码译码器
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计:Huffman编码/译码器
一、任务描述
任务:设计一个利用哈夫曼算法的编码和译码系统。
要求:建立一个文本文件,统计该文件中各字符频率,对各字符进行Huffman编码,将该文件翻译成Huffman编码文件,再将Huffman编码文件翻译成原文件。
“压缩文件”即:读文件、统计文件中的字符个数、对文件进行哈夫曼编码和译码、并将编码译码后的字符存储在文件中。
根据以上任务说明,设计数据结构,并设计程序完成功能。
二、问题分析
分析设计课题的要求,要求编程实现以下功能:
(1)创建最小Huffman树;
(2)统计文件中个字符的个数(频率);
(3)对个字符进行编码;
(4)将原文件翻译成编码文件;
(5)将编码文件翻译成原文件;
(6)创建yuanwj.txt、yima.txt、out.txt
三、数据结构设计
选用二叉树链表实现。有关的定义如下:
typedef struct node //哈夫曼树节点的结构体定义
{
char data;
int weight;
int parent,lc,rc;
}NODE;
typedef struct abc
{
char ch;
char str[20];
int s;
}ABC;
四、功能设计
(一)、主控菜单设计
为实现编码译码的操作功能,首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。
程序运行后,给出4个菜单项的内容和输入提示,如下:
1、键盘输入进行编码;
2、读文件进行编码;
3、译码;
4、退出系统;
(二)程序模块结构
由课题要求可将程序划分为以下几个模块:
(1)统计字符的频度tongji();
(2)建立哈弗曼树haffman() ;
(3)编码 huffmancode();
(4)输入input();
(5)输出output();
(6)译码yima();
(三)、函数调用关系
其中main()是主函数,它进行菜单驱动,根据选择项0~3调用相应的函数。main()函数使用switch循环实现重复选择。其循环结构如下:
switch(choice)
{
case 1: printf("\t请输入字符串:\n\t");fflush(stdin);
gets(s);
fp=fopen("D:\\yuanwj.txt","w");
fputs(s,fp);
fclose(fp);
case 2:tongji();
haffman();
huffmancode();
printf("您所输入的字母为:");
input();
printf("您所输入的字母对应的编码为:");
output();
getch();
break;
case 3: printf("译码为:");
yima(); getch();
break;
case 0:return;
}
(四)文件结构
1、mn.h:主菜单函数的声明
2、mn.cpp:主菜单函数的实现
3、main.cpp:主函数
(五)各函数算法设计
1、void tongji()
{
char str1[100];
char ch,s;
int i,j,count1=0,count2,k; //count1为存入字符的个数
FILE *fp;
if((fp=fopen("D:\\yuanwj.txt","rt"))==NULL)
{
printf("\n 无法打开!\n");
getchar();
exit(1);
}
ch=fgetc(fp);
i=1;
while(ch!='#')
{
str1[i]=ch; //将输入的字符存入str[i]
count1=i;
i++;
ch=fgetc(fp);
}
fclose(fp); //关闭文件
k=0;
for(i=1;i<=count1;i++)
{
if(str1[i]!='0') //字符串以'\0'结束
{
s=str1[i];
count2=0;
for(j=1;j<=count1;j++) //遍访字符串统计频率count2
if(str1[j]==s)
{
count2++;
str1[j]='0';
}
r[k].data=s; //将每个字符分别赋给r[k].data,这里已经没有重复字符
r[k].weight=count2; //频率即为权值
r[k].lc=r[k].rc=r[k].parent=0; //初始化
k++;
}
}
n=k;
}
//哈夫曼树的建立
2、void haffman()
{
int i,j,m1,m2,x1,x2; //m1,m2分别存放最小和次小权值,
//x1,x2分别存放m1和m2的结点地址即该结点在数组r中的下标
i=0;
while(i { m1=m2=32767; //初始化 x1=x2=0; for(j=0;j if((r[j].weight { m2=m1; x2=x1; m1=r[j].weight;