哈夫曼编解码完整c程序代码文档格式.docx
《哈夫曼编解码完整c程序代码文档格式.docx》由会员分享,可在线阅读,更多相关《哈夫曼编解码完整c程序代码文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
21
15
47
57
1
5
20
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
63
48
51
80
23
8
18
16
完整代码如下:
#include<
stdio.h>
iostream>
string>
#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"
;
cin>
>
state;
fflush(stdin);
//读取状态
switch(state)
{
case'
I'
n=inputHuff();
HuffmanTree(HT,w,n);
std:
\nHuffmanTree初始化完毕\n"
break;
case'
C'
coding(n);
D'
decoding(n);
P'
Print_tree(n,HT);
Q'
}
}while(state!
='
);
}
voidmenu()//显示菜单函数
std:
===========HuffmanCoding===========\n"
input\t\tdo\n"
I\t\tInit_HUffTree\n"
//初始化huffmantree
C\t\tCoding\n"
//对ToBeTran.txt文件中的字符进行编码到CodeFile.txt中
D\t\tUnCoding\n"
//对CodeFile.txt中的01序列进行解码到TextFile.txt
P\t\tPrintTree\n"
//打印哈夫曼树
Q\t\tquit\n"
请初始化哈夫曼树再执行后面的操作\n"
intinputHuff()//输入各个字母及其权值
inti=1,n=0;
intww[28];
charcc[28];
while
(1)
inputtheletter(input'
#'
tostop):
cc[i]=std:
cin.get();
if(cc[i]=='
)
break;
inputtheweight:
ww[i];
n++;
i++;
}
w=(int*)malloc(sizeof(int)*(n+1));
c=(char*)malloc(sizeof(char)*(n+1));
for(i=0;
i<
n+1;
i++)
w[i]=ww[i];
c[i]=cc[i];
returnn;
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;
m;
HT[i].weight=i<
=n?
w[i]:
0;
HT[i].lchild=HT[i].rchild=HT[i].parent=0;
for(i=n+1;
=m;
{
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<
i;
j++)
if(HT[j].parent==0)
s1=j;
s2=j;
gotoflag;
flag:
for(j=s1+1;
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以凹凸表形式打印已建好的赫夫曼树:
=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"
}
fclose(fp);
\n此字符形式的哈夫曼树已写入文件treeprint.txt中.\n\n"
\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<
s;
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;
HuffmanTree(HT,w,n);
visite(HT,2*n-1,2,0);
fflush(stdin);
translatef("
ToBeTran.txt"
CodeFile.txt"
n);
fp1=fopen("
r"
\n编码已写入文件treeprint.txt中.\n"
fclose(fp1);
voiddecoding(intn)//对CodeFile.txt中的01序列进行解码到TextFile.txt
FILE*fp1,*fp2;
fp2=fopen("
TextFile.txt"
w"
while(uncodef(fp1,fp2,HT,2*n-1));
\n解码已写入文件TextFile.txt中.\n"
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'
if(HT[i].lchild==0)
for(j=0;
rear;
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;
k;
code[i][j]=stack[j];
code[i][j]='
rear--;
return;
voidtranslatef(char*scource,char*save,intn)//读取文件中的字母序列,并根据code[][]将其转换成01序列输出
charp='
inti=0,j=0,k=0;
fp1=fopen(scource,"
fp2=fopen(save,"
p=fgetc(fp1);
\n得到的编码为:
while(p!
=EOF)
for(i=0;
=n;
if(c[i]==p)
for(j=0;
N&
code[i][j]!
{
fputc(code[i][j],fp2);
putchar(code[i][j]);
k++;
if(k>
=50)
{
k=0;
putchar('
\n'
}
}
p=fgetc(fp1);
booluncodef(FILE*fp1,FILE*fp2,HuffHT,intn)//通过对树的访问,把文件中01序列转换成一个字母输出。
本函数需循环调用,当读到'
时返回false
if(!
fp1||!
fp2)
printf("
error"
exit(0);
if(HT[n].lchild==0)
fputc(c[n],fp2);
returntrue;
else
if(p==EOF)
returnfalse;
if(p=='
uncodef(fp1,fp2,HT,HT[n].lchild);
elseif(p=='
uncodef(fp1,fp2,HT,HT[n].rchild);
returntrue;
/*以下在初始化哈夫曼树时复制粘贴可用,注意第一个为空格,weight为186,复制粘贴时要包括它.输入以#号结束
186
A
64
B
13
C
22
D
32
E
F
21
G
15
H
47
I
57
J
1
K
5
L
M
20
N
O
63
P
Q
R
48
S
51
T
80
U
23
V
8
W
18
X
Y
16
Z
#
*/