哈夫曼编解码完整c程序代码.docx
- 文档编号:9221943
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:15
- 大小:18.38KB
哈夫曼编解码完整c程序代码.docx
《哈夫曼编解码完整c程序代码.docx》由会员分享,可在线阅读,更多相关《哈夫曼编解码完整c程序代码.docx(15页珍藏版)》请在冰豆网上搜索。
哈夫曼编解码完整c程序代码
1)内容:
利用Huffman编码进行通信可以大大提高信道的利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据进行预先编码,在接收端进行解码。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/解码系统。
2)要求:
一个完整的huffman编解码系统应该具有以下功能:
初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立Huffman树,并将它存入hfmTree中。
编码(Encoding)。
利用已经建好的Huffman树(如果不在内存,则应从文件hfmTree中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件hfmTree中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
解码(Decoding)。
利用已经建立好的Huffman树将文件CodeFile中的代码进行解码,结果存入TextFile中。
打印代码文件(Print)。
将文件CodeFile以紧凑的格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件CodePrint中。
打印Huffman树(TreePrinting)。
将已经在内存中的Huffman树以直观的形式(树或者凹入的形式)显示在终端上,同时将此字符形式的Huffman树写入文件TreePrint中。
3)测试数据:
用下表给出的字符集和频度的实际统计数据建立Huffman树,并对以下报文进行编码和译码:
“THISPROGRAMISMYFAVORITE”。
字符
A
B
C
D
E
F
G
H
I
J
K
L
M
频度
186
64
13
22
32
103
21
15
47
57
1
5
32
20
字符
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
频度
57
63
15
1
48
51
80
23
8
18
1
16
1
完整代码如下:
#include
#include
#include
#defineN100
int*w;
char*c,stack[N],code[N][N];
ints1,s2;
typedefstructHuffmanTree
{
intweight;
intparent;
intlchild;
intrchild;
}HuffmanTree,*Huff;
voidmenu(void);
voidSelect(structHuffmanTreeHT[],inti);
voidHuffmanTree(Huff&HT,int*w,intn);
voidvisite(HuffHT,inti,intflag,intrear);
voidtranslatef(char*scource,char*save,intn);
booluncodef(FILE*fp1,FILE*fp2,HuffHT,intn);
intinputHuff();
voidscreanio(intn);
voidfileio(intn);
intinitHuff();
voidPrint_tree(intn,HuffHT);
voidConvert_tree(HuffHT,unsignedcharT[100][100],inttt[100][100],ints,int*i,intj);
voiddecoding(intn);
voidcoding(intn);
voidmain()
{
intn=0;
menu();
HuffHT;
charstate;
do
{
std:
:
cout<<"input:
\n";
std:
:
cin>>state;fflush(stdin);//读取状态
switch(state)
{
case'I':
n=inputHuff();HuffmanTree(HT,w,n);std:
:
cout<<"\nHuffmanTree初始化完毕\n";break;
case'C':
coding(n);break;
case'D':
decoding(n);break;
case'P':
Print_tree(n,HT);break;
case'Q':
break;
}
}while(state!
='Q');
}
voidmenu()//显示菜单函数
{
std:
:
cout<<"===========HuffmanCoding===========\n";
std:
:
cout<<"input\t\tdo\n";
std:
:
cout<<"I\t\tInit_HUffTree\n";//初始化huffmantree
std:
:
cout<<"C\t\tCoding\n";//对ToBeTran.txt文件中的字符进行编码到CodeFile.txt中
std:
:
cout<<"D\t\tUnCoding\n";//对CodeFile.txt中的01序列进行解码到TextFile.txt
std:
:
cout<<"P\t\tPrintTree\n";//打印哈夫曼树
std:
:
cout<<"Q\t\tquit\n";
std:
:
cout<<"请初始化哈夫曼树再执行后面的操作\n";
}
intinputHuff()//输入各个字母及其权值
{
inti=1,n=0;
intww[28];
charcc[28];
while
(1)
{
std:
:
cout<<"inputtheletter(input'#'tostop):
";
cc[i]=std:
:
cin.get();fflush(stdin);
if(cc[i]=='#')
break;
std:
:
cout<<"inputtheweight:
";
std:
:
cin>>ww[i];fflush(stdin);
n++;
i++;
}
w=(int*)malloc(sizeof(int)*(n+1));
c=(char*)malloc(sizeof(char)*(n+1));
for(i=0;i { w[i]=ww[i]; c[i]=cc[i]; } returnn; } voidHuffmanTree(Huff&HT,int*w,intn)//初始化哈夫曼树 { intm,i; m=n*2-1; HT=(structHuffmanTree*)malloc(sizeof(structHuffmanTree)*(m+1)); HT[0].lchild=0; HT[0].parent=0; HT[0].rchild=0; HT[0].weight=0; for(i=1;i { HT[i].weight=i<=n? w[i]: 0; HT[i].lchild=HT[i].rchild=HT[i].parent=0; } for(i=n+1;i<=m;i++) { Select(HT,i); HT[i].lchild=s1; HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; HT[s1].parent=HT[s2].parent=i; } } voidSelect(structHuffmanTreeHT[],inti)//在HT[1..i-1]中选择parent为0且weight为最小的两个结点 { intj; for(j=1;j { if(HT[j].parent==0) { s1=j;s2=j;gotoflag; } } flag: for(j=s1+1;j { if(HT[j].parent==0) { if(HT[s1].weight>=HT[j].weight) { s2=s1; s1=j; } if(HT[s2].weight>HT[j].weight&&j! =s1) s2=j; if(s1==s2)s2=j; } } } voidPrint_tree(intn,HuffHT)//以凹入法的形式打印树 { unsignedcharT[100][100]; inttt[100][100]; inti,j,m=0; FILE*fp; Convert_tree(HT,T,tt,0,&m,2*n-1);//将内存中的赫夫曼树转换成凹凸表形式的树,存于数组T中 if((fp=fopen("treeprint.txt","wb+"))==NULL) printf("Openfiletreeprint.txterror! \n"); printf("\n以凹凸表形式打印已建好的赫夫曼树: \n"); for(i=1;i<=2*n-1;i++) { for(j=0;T[i][j]! =0;j++) { if(T[i][j]==''){printf("");fputc(T[i][j],fp);} else {printf("%d",tt[i][j]);fprintf(fp,"%d\n\n\n",tt[i][j]);} } printf("\n"); } fclose(fp); printf("\n此字符形式的哈夫曼树已写入文件treeprint.txt中.\n\n"); printf("\n文件treeprint.txt的打开方式要为写字板,若打开方式为记事本,则无法显示凹凸表的形式\n"); } voidConvert_tree(HuffHT,unsignedcharT[100][100],inttt[100][100],ints,int*i,intj)//将内存中的赫夫曼树转换成凹凸表形式的树,存于数组T中 { intk,l; l=++(*i); for(k=0;k T[l][k]=''; T[l][k]='#'; tt[l][k]=HT[j].weight; if(HT[j].lchild) Convert_tree(HT,T,tt,s+1,i,HT[j].lchild); if(HT[j].rchild) Convert_tree(HT,T,tt,s+1,i,HT[j].rchild); T[l][++k]='\0'; } voidcoding(intn)//对文件ToBeTran.txt编码到CodeFile.txt { FILE*fp1; HuffHT; HuffmanTree(HT,w,n); visite(HT,2*n-1,2,0); fflush(stdin); translatef("ToBeTran.txt","CodeFile.txt",n); fp1=fopen("CodeFile.txt","r"); printf("\n编码已写入文件treeprint.txt中.\n"); fclose(fp1); } voiddecoding(intn)//对CodeFile.txt中的01序列进行解码到TextFile.txt { FILE*fp1,*fp2; HuffHT; HuffmanTree(HT,w,n); fp1=fopen("CodeFile.txt","r"); fp2=fopen("TextFile.txt","w"); while(uncodef(fp1,fp2,HT,2*n-1)); printf("\n"); printf("\n解码已写入文件TextFile.txt中.\n"); fclose(fp1); fclose(fp2); } voidvisite(HuffHT,inti,intflag,intrear)//通过递归调用visite()函数,得到各个字母的编码,存储于全局变量code[][]中 { intj=0,k=0; if(flag==0) { stack[rear]='0'; rear++; } elseif(flag==1) { stack[rear]='1'; rear++; } if(HT[i].lchild==0) { for(j=0;j { code[i][j]=stack[j]; } code[i][j]='#'; rear--; return; } visite(HT,HT[i].lchild,0,rear); visite(HT,HT[i].rchild,1,rear); k=rear; for(j=0;j { code[i][j]=stack[j]; } code[i][j]='#'; rear--; return; } voidtranslatef(char*scource,char*save,intn)//读取文件中的字母序列,并根据code[][]将其转换成01序列输出 { FILE*fp1,*fp2; charp=''; inti=0,j=0,k=0; fp1=fopen(scource,"r"); fp2=fopen(save,"w"); p=fgetc(fp1); printf("\n得到的编码为: \n"); while(p! =EOF) { for(i=0;i<=n;i++) { if(c[i]==p) { for(j=0;j ='#';j++) { fputc(code[i][j],fp2);putchar(code[i][j]);k++; if(k>=50) { k=0; putchar('\n'); } } } } p=fgetc(fp1); } fclose(fp1); fclose(fp2); } booluncodef(FILE*fp1,FILE*fp2,HuffHT,intn)//通过对树的访问,把文件中01序列转换成一个字母输出。 本函数需循环调用,当读到'\n'时返回false { charp=''; if(! fp1||! fp2) { printf("error"); exit(0); } if(HT[n].lchild==0) { fputc(c[n],fp2); returntrue; } else { p=fgetc(fp1); if(p==EOF) { returnfalse; } } if(p=='0') { uncodef(fp1,fp2,HT,HT[n].lchild); } elseif(p=='1') { uncodef(fp1,fp2,HT,HT[n].rchild); } returntrue; } /*以下在初始化哈夫曼树时复制粘贴可用,注意第一个为空格,weight为186,复制粘贴时要包括它.输入以#号结束 186 A 64 B 13 C 22 D 32 E 103 F 21 G 15 H 47 I 57 J 1 K 5 L 32 M 20 N 57 O 63 P 15 Q 1 R 48 S 51 T 80 U 23 V 8 W 18 X 1 Y 16 Z 1 # */
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈夫曼编 解码 完整 程序代码