哈夫曼树编码译码实验报告材料Word格式.docx
《哈夫曼树编码译码实验报告材料Word格式.docx》由会员分享,可在线阅读,更多相关《哈夫曼树编码译码实验报告材料Word格式.docx(19页珍藏版)》请在冰豆网上搜索。
![哈夫曼树编码译码实验报告材料Word格式.docx](https://file1.bdocx.com/fileroot1/2022-11/22/11880fd8-f092-47cb-ad22-6906c3243ac5/11880fd8-f092-47cb-ad22-6906c3243ac51.gif)
/*floor(),ceil(),abs()*/
process.h>
/*exit()*/
/*函数结果状态代码*/
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
/*#defineOVERFLOW-2因为在math.h中已定义OVERFLOW的值为3,故去掉此行*/
typedefintStatus;
/*Status是函数的类型,其值是函数结果状态代码,如OK等*/
typedefintBoolean;
/*Boolean是布尔类型,其值是TRUE或FALSE*/
2.将哈夫曼树存储结构定义放在一个头文件:
取名为huffermandef.h。
typedefstruct
{charch;
unsignedintweight;
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;
/*动态分配数组存储赫夫曼树*/
typedefchar**HuffmanCode;
/*动态分配数组存储赫夫曼编码表*/
3.将哈夫曼树的基本操作算法也集中放在一个文件之中,取名为huffermanalgo.h。
intmin1(HuffmanTreet,inti)
{/*函数voidselect()调用*/
intj,flag;
unsignedintk=UINT_MAX;
/*取k为不小于可能的值*/
for(j=1;
j<
=i;
j++)
if(t[j].weight<
k&
&
t[j].parent==0)
k=t[j].weight,flag=j;
t[flag].parent=1;
returnflag;
}
voidselect(HuffmanTreet,inti,int*s1,int*s2)
{/*s1为最小的两个值中序号小的那个*/
intj;
*s1=min1(t,i);
*s2=min1(t,i);
if(*s1>
*s2)
{
j=*s1;
*s1=*s2;
*s2=j;
voidHuffmanCoding(HuffmanTree&
HT,HuffmanCode&
HC,int*w,char*ch,intn)/*算法6.12*/
{/*w存放n个字符的权值(均>
0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC*/
intm,i,j,s1,s2,start;
unsignedc,f;
HuffmanTreep;
char*cd;
if(n<
=1)
return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
/*0号单元未用*/
for(p=HT+1,i=1;
i<
=n;
++i,++p,++w,++ch)
(*p).ch=*ch;
(*p).weight=*w;
(*p).parent=0;
(*p).lchild=0;
(*p).rchild=0;
for(;
=m;
++i,++p)
{(*p).ch='
*'
;
for(i=n+1,j=1;
++i,j++)/*建赫夫曼树*/
{/*在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2*/
select(HT,i-1,&
s1,&
s2);
printf("
第%d次比较min1与min2:
%d%d"
j,HT[s1].weight,HT[s2].weight);
\n"
);
HT[s1].parent=HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
/*从叶子到根逆向求每个字符的赫夫曼编码*/
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
/*分配n个字符编码的头指针向量([0]不用)*/
cd=(char*)malloc(n*sizeof(char));
/*分配求编码的工作空间*/
cd[n-1]='
\0'
/*编码结束符*/
for(i=1;
i++)
{/*逐个字符求赫夫曼编码*/
start=n-1;
/*编码结束符位置*/
for(c=i,f=HT[i].parent;
f!
=0;
c=f,f=HT[f].parent)
/*从叶子到根逆向求编码*/
if(HT[f].lchild==c)
cd[--start]='
0'
else
1'
HC[i]=(char*)malloc((n-start)*sizeof(char));
/*为第i个字符编码分配空间*/
strcpy(HC[i],&
cd[start]);
/*从cd复制编码(串)到HC*/
free(cd);
/*释放工作空间*/
voidReadDataFile(char*fileName1,int*wt,char*chh)//读初始化文件容
{
FILE*fp1;
charch;
intw,i=0;
if((fp1=fopen(fileName1,"
r"
))==NULL)
\nerroronopen%s!
"
fileName1);
exit
(1);
\n文件容:
while(!
feof(fp1))
fscanf(fp1,"
%c"
&
ch);
if(ch=='
\n'
)continue;
//读到换行符,跳过,读下一行
chh[i]=ch;
ch=%c"
ch);
%5d"
w);
//fscanf中的格式化要加\n,文件指针才会指向下一行
wt[i]=w;
weight=%5d\n"
w);
i++;
}
fclose(fp1);
voidWriteDataFile(char*fileName1)//将初始化信息写入文件中
charc;
intweight;
w"
请输入相关字符及字符的权值,#结束:
c=getchar();
while((c=getchar())!
='
#'
)
fprintf(fp1,"
c);
//将字符写入文件
scanf("
%d"
weight);
%5d\n"
weight);
//将字符的权值写入文件,采用fprintf格式化写入
voidWriteToBeTran(char*fileName2)//将初始化信息写入文件中
FILE*fp2;
inti=0;
if((fp2=fopen(fileName2,"
fileName2);
请输入需要编译的文本,#结束:
ch=getchar();
while(ch!
fputc(ch,fp2);
putchar(10);
fclose(fp2);
voidReadToBeTran(char*fileName2,charstr[])//读初始化文件容
feof(fp2))
fscanf(fp2,"
str[i++]=ch;
str[i]='
voidWriteCode(char*fileName3,char*fileName4,HuffmanTree&
HC,intn)
{FILE*fp3,*fp4;
inti;
if((fp3=fopen(fileName3,"
))==NULL)
{printf("
\nerroronopen%s!
fileName3);
exit(0);
if((fp4=fopen(fileName4,"
fileName4);
feof(fp3))
ch=fgetc(fp3);
if(ch==HT[i].ch)
fprintf(fp4,"
%s"
HC[i]);
fclose(fp3);
fclose(fp4);
voidReadCode(char*fileName4)
{FILE*fp4;
\n输出编码后的文件容:
feof(fp4))
ch=fgetc(fp4);
voidyima(HuffmanTree&
HT,intn,charstr4[],charhh[])
{inti,j,m=0;
for(i=0,j=2*n-1;
str4[i]!
i++)
if(str4[i]=='
HT[j].lchild!
=0)
{j=HT[j].lchild;
if(HT[j].lchild==0||HT[j].rchild==0)
{hh[m++]=HT[j].ch;
j=2*n-1;
elseif(str4[i]=='
HT[j].rchild!
{j=HT[j].rchild;
hh[m]='
voidWriteCodeFile(char*fileName5)//将初始化信息写入文件中
FILE*fp5;
if((fp5=fopen(fileName5,"
fileName5);
请输入需要译的代码,#结束:
fputc(ch,fp5);
fclose(fp5);
voidReadCodeFile(char*fileName5,charstr4[])//读初始化文件容
feof(fp5))
{ch=fgetc(fp5);
str4[i++]=ch;
str4[i]='
voidWriteTextFile(char*fileName6,charhh[])
{FILE*fp6;
if((fp6=fopen(fileName6,"
fileName6);
for(i=0;
hh[i]!
{ch=hh[i];
fprintf(fp6,"
fclose(fp6);
voidReadTextFile(char*fileName6)
\n输出译码后的文件容:
feof(fp6))
{ch=fgetc(fp6);
4.将函数的测试和主函数组合成一个文件,取名为huffermanuse.cpp。
#include"
huffermanpubuse.h"
huffermandef.h"
huffermanalgo.h"
voidmain()
HuffmanTreeHT;
HuffmanCodeHC;
int*wt,n,m,i,y,x,s1,s2;
charstr[100];
charstr1[100],str2[100],str3[100],str4[100],str5[100],str6[100];
char*chh;
charhh[100];
请输入权值的个数(>
1):
n);
wt=(int*)malloc((n)*sizeof(int));
chh=(char*)malloc((n)*sizeof(char));
请输入数据文件名:
str1);
WriteDataFile(str1);
ReadDataFile(str1,wt,chh);
HuffmanCoding(HT,HC,wt,chh,n);
nodeletterweightparentlchildrchild"
%4d%6c%7d%8d%8d%8d"
i,HT[i].ch,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
printf("
***********哈夫曼树编码译码***********\n"
***********1.对哈夫曼树进行编码***********\n"
***********2.对文本文件中的文本进行编码***********\n"
***********2.对代码文件中的代码进行译码***********\n"
***********3.感谢使用***********\n"
while(x)
请输入要实现功能的代码:
scanf("
y);
switch(y)
{
case1:
赫夫曼编码为:
for(i=1;
{printf("
%c的编码为:
*(chh+i-1));
puts(HC[i]);
}break;
case2:
请输入文本文件名:
str2);
WriteToBeTran(str2);
ReadToBeTran(str2,str);
printf("
请输入文本编码存放文件名:
str5);
WriteCode(str2,str5,HT,HC,n);
ReadCode(str5);
break;
case3:
请输入代码文件名:
str3);
WriteCodeFile(str3);
ReadCodeFile(str3,str4);
yima(HT,n,str4,hh);
请输入译文存放文件名:
str6);
WriteTextFile(str6,hh);
ReadTextFile(str6);
case4:
感谢使用!
x=0;
default:
error!
break;
}
保存,编译,连接,运行。
七、实验结果:
八、实验总结及心得体会:
九、对本实验过程及方法、手段的改进建议:
报告评分:
指导教师签字:
批阅日期:
注意:
●实验报告以纸质文档形式上交。
实验报告将记入平时成绩;
●每次实验开始时,交上一次的实验报告,否则将扣除此次实验成绩。