哈夫曼编解码完整c程序代码.docx

上传人:b****7 文档编号:9221943 上传时间:2023-02-03 格式:DOCX 页数:15 大小:18.38KB
下载 相关 举报
哈夫曼编解码完整c程序代码.docx_第1页
第1页 / 共15页
哈夫曼编解码完整c程序代码.docx_第2页
第2页 / 共15页
哈夫曼编解码完整c程序代码.docx_第3页
第3页 / 共15页
哈夫曼编解码完整c程序代码.docx_第4页
第4页 / 共15页
哈夫曼编解码完整c程序代码.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

哈夫曼编解码完整c程序代码.docx

《哈夫曼编解码完整c程序代码.docx》由会员分享,可在线阅读,更多相关《哈夫曼编解码完整c程序代码.docx(15页珍藏版)》请在冰豆网上搜索。

哈夫曼编解码完整c程序代码.docx

哈夫曼编解码完整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

#

*/

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1