数据结构课程设计哈夫曼编码译码器.docx
《数据结构课程设计哈夫曼编码译码器.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计哈夫曼编码译码器.docx(25页珍藏版)》请在冰豆网上搜索。
![数据结构课程设计哈夫曼编码译码器.docx](https://file1.bdocx.com/fileroot1/2022-12/17/df05ac0e-cef7-4bcf-8b5c-8eebc10a0300/df05ac0e-cef7-4bcf-8b5c-8eebc10a03001.gif)
数据结构课程设计哈夫曼编码译码器
题目一:
哈夫曼编码与译码
一、任务
设计一个利用哈夫曼算法的编码与译码系统,重复地显示并处理以下项目,直到选择退出为止。
要求:
1) 将权值数据存放在数据文件(文件名为data、txt,位于执行程序的当前目录中);
2) 初始化:
键盘输入字符集统计字符权值、自定义26个字符与26个权值、统计文件中一篇英文文章中26个字母,建立哈夫曼树;
3) 编码:
利用建好的哈夫曼树生成哈夫曼编码;
4) 输出编码(首先实现屏幕输出,然后实现文件输出);
5)译码(键盘接收编码进行译码、文件读入编码进行译码);
6) 界面优化设计。
二、流程图
三、代码分解
//头文件
#include
#include
#include
#include
#defineN1000
#defineM2*N-1
#defineMAXcode6000
//函数声明
voidcount(CHar&ch,HTNodeht[]);
voideditHCode(HTNodeht[],HCodehcd[],CHar&ch,intn,charbianma[]);//编码函数
voidprintyima(HTNodeht[],HCodehcd[],intn,charbianma[]);//译码函数
voidcreatHT(HTNodeht[],intn);
voidCreateHCode(HTNodeht[],HCodehcd[],intn);
voidDispHCode(HTNodeht[],HCodehcd[],intn);
voidinput_key(CHar&ch);
voidinput_&ch);
voidinput_cw(HTNodeht[]);
voidbianma1(HTNodeht[],HCodehcd[],CHar&ch,intn,charbianma[]);
voidbianma2(HTNodeht[],HCodehcd[],CHar&ch,intn,charbianma[]);
voidyima1(HTNodeht[],HCodehcd[],intn,charbianma[]);
voidyima2(HTNodeht[],HCodehcd[],intn,charbianma[]);
voidcreat_cw();
voidbianmacaidan();
voidyimacaidan();
voidbianmayima();
intcaidan();
//结构体
typedefstruct
{
chardata;
intparent;
intweight;
intlchild;
intrchild;
}HTNode;
typedefstruct
{
charcd[N];
intstart;
}HCode;
typedefstruct
{
chars[N];
intnum;
}CHar;
CHarch;
HTNodeht[M];
HCodehcd[N];
//主函数
intmain()
{
intxh;
while
(1)
{
system("color1f");//操作菜单背景颜色
xh=caidan();//调用菜单函数
switch(xh)//switch语句
{
case1:
system("cls");creat_cw();break;
case2:
system("cls");creatHT(ht,n);break;
case3:
system("cls");CreateHCode(ht,hcd,n);DispHCode(ht,hcd,n);break;
case4:
system("cls");bianmayima();break;
case0:
system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t\t\t感谢使用本系统!
\n\n\n\n\n\n\n\t\t\t");exit(0);
default:
system("cls");putchar('\a');
printf("\n\t\t输入有误,请重新输入:
\n");break;
}
}
return0;
}
//菜单函数
intcaidan()//菜单函数模块//
{
intxh;
printf("\n\n\n");
printf("\t\t欢迎使用哈夫曼编码译码系统\n");
printf("\t\t\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*==*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*==*\n");
printf("\t\t*=1、建立字符权值=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*==*\n");
printf("\t\t*=2、建立并输出哈夫曼树=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*==*\n");
printf("\t\t*=3、生成并查瞧哈夫曼编码=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*==*\n");
printf("\t\t*=4、编码与译码=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*==*\n");
printf("\t\t*=0、退出系统=*\n");
printf("\t\t*==*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\n\t\t请输入序号进行选择:
");
scanf("%d",&xh);
returnxh;//返回从键盘接收的选项
}
voidbianmayima()
{
intxh;
while
(1)
{
printf("\n\n\n\n\n");
printf("\t\t编码与译码\n");
printf("\t\t\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=1、编码=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=2、译码=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=0、返回上级菜单=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\n\t\t请输入序号进行选择:
");
scanf("%d",&xh);
switch(xh)//switch语句
{
case1:
system("cls");bianmacaidan();break;
case2:
system("cls");yimacaidan();break;
case0:
system("cls");return;
default:
system("cls");putchar('\a');
printf("\n\t\t输入有误,请重新输入:
\n");break;
}
}
}
voidyimacaidan()
{
intxh;
while
(1)
{
printf("\n\n\n\n\n");
printf("\t\t译码\n");
printf("\t\t\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=1、键盘输入编码进行译码=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=2、文件读入编码进行译码=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=0、返回上级菜单=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\n\t\t请输入序号进行选择:
");
scanf("%d",&xh);
switch(xh)//switch语句
{
case1:
system("cls");yima1(ht,hcd,n,bianma);break;
case2:
system("cls");yima2(ht,hcd,n,bianma);break;
case0:
system("cls");return;
default:
system("cls");putchar('\a');
printf("\n\t\t输入有误,请重新输入:
\n");break;
}
}
}
voidbianmacaidan()
{
intxh;
while
(1)
{
printf("\n\n\n\n\n");
printf("\t\t编码\n");
printf("\t\t\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=1、键盘输入字符集编码=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=2、文件读入文章编码=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=0、返回上级菜单=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\n\t\t请输入序号进行选择:
");
scanf("%d",&xh);
switch(xh)//switch语句
{
case1:
system("cls");bianma1(ht,hcd,ch,n,bianma);break;
case2:
system("cls");bianma2(ht,hcd,ch,n,bianma);break;
case0:
system("cls");return;
default:
system("cls");putchar('\a');
printf("\n\t\t输入有误,请重新输入:
\n");break;
}
}
}
voidcreat_cw()
{
intxh2;
while
(1)
{
printf("\n\n\n\n\n");
printf("\t\t建立字符权值\n");
printf("\t\t\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=1、从键盘输入字符集进行统计=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=2、从文件读入字符集统计=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=3、自定义字符权值=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\t\t*=0、返回上级菜单=*\n");
printf("\t\t*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*\n");
printf("\n\t\t请输入序号进行选择:
");
scanf("%d",&xh2);
switch(xh2)//switch语句
{
case1:
system("cls");input_key(ch);break;
case2:
system("cls");input_);break;
case3:
system("cls");input_cw(ht);break;
case0:
system("cls");return;
default:
system("cls");putchar('\a');
printf("\n\t\t输入有误,请重新输入:
\n");break;
}
}
}
//建立字符权值模块
voidinput_key(CHar&ch)
{
inti,j=0;
charst[N];
printf("请输入字符集(以‘#’结束):
\n");
for(i=0;i{
scanf("%c",&st[i]);
if(st[i]=='#')
{st[i]='\0';break;}
}
strcpy(ch、s,st);
ch、num=strlen(st);
count(ch,ht);
printf("按任意键返回!
");
getch();
system("cls");
return;
}
voidinput_&ch)
{
inti;
;
char[20];
printf("请输入要打开的文件名(*、txt):
");
scanf("%s",&);
if((fp=fopen(,"r"))==NULL)
{
printf("\n\t\t文件打开失败!
!
!
");
return;
}
for(i=0;!
feof(fp);i++)
{
fread(&ch、s[i],sizeof(char),1,fp);
}
ch、num=strlen(ch、s);
printf("读入成功!
\n");
printf("文件中的字符集为:
%s\n",ch、s);
fclose(fp);
count(ch,ht);
printf("按任意键返回!
");
getch();
system("cls");
return;
}
voidinput_cw(HTNodeht[])
{
inti,w,s,j;
chara;
printf("要输入的字符总个数就是?
:
");
scanf("%d",&s);
n=s;
printf("请输入字符及其权值:
\n");
for(i=0;i
{
printf("请输入第%d个字母:
",i+1);
scanf("%s",&a);
ht[i]、data=a;
printf("请输入其权值:
");
scanf("%d",&w);
ht[i]、weight=w;
}
FILE*fp;
if((fp=fopen("data、txt","w"))==0)
{
printf("\n\t\t文件打开失败!
!
!
");
return;
}
printf("\n定义权值成功!
\n\n");
printf("各字符及其权值为:
\n\n");
fprintf(fp,"各字符及其权值为:
\n");
printf("字符\t权值");
fprintf(fp,"字符\t权值");
for(j=0;j
{printf("\n");
fprintf(fp,"\n");
printf("%-8c%-8d",ht[j]、data,ht[j]、weight);
fprintf(fp,"%-8c%-8d%",ht[j]、data,ht[j]、weight);
}
printf("\n");
printf("\n字符权值已输出至文件“data、txt”!
");
fclose(fp);
printf("输入完成,按任意键返回!
");
getch();
system("cls");
return;
}
//统计字符权值函数
voidcount(CHar&ch,HTNodeht[])
{
inti,j,m=0;
charc[N];
intsum[N]={0};
for(i=0;ch、s[i]!
='\0';i++)
{
for(j=0;jif(ch、s[i]==c[j]||(c[j]>='a'&&c[j]<='z'&&ch、s[i]+32==c[j]))break;
if(jsum[j]++;
else
{
if(ch、s[i]>='A'&&ch、s[i]<='Z')
c[j]=ch、s[i]+32;
elsec[j]=ch、s[i];
sum[j]++;
m++;
}
}
for(i=0;i{
ht[i]、data=c[i];
ht[i]、weight=sum[i];
}
n=m;
FILE*fp;
if((fp=fopen("data、txt","w"))==0)
{
printf("\n\t\t文件打开失败!
!
!
");
return;
}
printf("\n统计权值成功!
\n\n");
printf("各字符及其权值为:
\n\n");
fprintf(fp,"各字符及其权值为:
\n");
printf("字符\t权值");
fprintf(fp,"字符\t权值");
for(j=0;j{printf("\n");
fprintf(fp,"\n");
printf("%-8c%-8d",ht[j]、data,ht[j]、weight);
fprintf(fp,"%-8c%-8d%",ht[j]、data,ht[j]、weight);
}
printf("\n");
printf("\n字符权值已输出至文件“data、txt”!
");
fclose(fp);
}
//构造哈夫曼树
voidcreatHT(HTNodeht[],intn)
{
FILE*fp;
if((fp=fopen("哈夫曼树、txt","w"))==0)
{
printf("\n\t\t文件打开失败!
!
!
");
return;
}
inti,j,k,lnode,rnode;
intmin1,min2;
for(i=0;i<2*n-1;i++)
ht[i]、parent=ht[i]、lchild=ht[i]、rchild=-1;
for(i=n;i<2*n-1;i++)
{
min1=min2=32767;
lnode=rnode=-1;
for(k=0;k<=i-1;k++)
if(ht[k]、parent==-1)
{
if(ht[k]、weight{
min2=min1;rnode=lnode;
min1=ht[k]、weight;lnode=k;
}
elseif(ht[k]、weight{
min2=ht[k]、weight;rnode=k;
}
}
ht[lnode]、parent=i;ht[rnode]、parent=i;
ht[i]、weight=ht[lnode]、weight+ht[rnode]、weight;
ht[i]、lchild=lnode;ht[i]、rchild=rnode;
}
printf("建立huffman树成功!
\n");
printf("输出huffman树:
\n");
fprintf(fp,"输出huffman树:
\n");
printf("\t字符\t权值\t父节点\t左子节点\t右子节点");
fprintf(fp,"\t字符\t权值\t父节点\t左子节点\t右子节点");
for(j=1;j
{printf("\n");
fprintf(fp,"\n");
printf("\t%-8c%-8d%-10d%-14d%-10d",ht[j]、data,ht[j]、weight,ht[j]、parent,ht[i]、lchild,ht[j]、rchild);
fprintf(fp,"\t%-8c%-8d%-10d%-14d%-10d",ht[j]、data,ht[j]、weight,ht[j]、parent,ht[i]、lchild,ht[j]、rchild);
}
printf("\n");
printf("哈夫曼树已输出至文件“哈夫曼树、txt”!
按任意键返回!
");
fclose(fp);
getch();
system("cls");
return;
}
//生成哈夫曼编码
voidCreateHCode(HTNodeht[],HCodehcd[],intn)
{
inti,f,c,j=0;
HCodehc;
for(i=0;i{
hc、start=n;c=i;
hc、cd[hc、start--]='0';
f=ht[i]、parent;
while(f!
=-1)
{
if(ht[f]、lchild==c)
hc、cd[hc、start--]='0';
else
hc、cd[hc、start--]='1';
c=f;f=ht[f]、parent;
}
hc、start++;
for(j=0;jhc、cd[j]='';
hcd[i]=hc;
}
}
voidDispHCode