哈弗曼编码与译码.docx

上传人:b****6 文档编号:3253314 上传时间:2022-11-21 格式:DOCX 页数:11 大小:18.43KB
下载 相关 举报
哈弗曼编码与译码.docx_第1页
第1页 / 共11页
哈弗曼编码与译码.docx_第2页
第2页 / 共11页
哈弗曼编码与译码.docx_第3页
第3页 / 共11页
哈弗曼编码与译码.docx_第4页
第4页 / 共11页
哈弗曼编码与译码.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

哈弗曼编码与译码.docx

《哈弗曼编码与译码.docx》由会员分享,可在线阅读,更多相关《哈弗曼编码与译码.docx(11页珍藏版)》请在冰豆网上搜索。

哈弗曼编码与译码.docx

哈弗曼编码与译码

哈弗曼编码与译码

一个完整的系统应具有以下功能:

(1)I:

初始化(Initialization)。

从终端读入字符集大小n,以及n个字符和n个权值,建立赫夫曼树,并将它存于文件hfmTree中。

(2)E:

编码(Encoding)。

利用已建好的赫夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。

(3)D:

译码(Decoding)。

利用已建好的赫夫曼树将文件CodeFile中的代码进行译码,结果存入文件Textfile中。

以下为选做:

(4)P:

印代码文件(Print)。

将文件CodeFile以紧凑格式显示在终端上,每行50个代码。

同时将此字符形式的编码文件写入文件CodePrin中。

(5)T:

印赫夫曼树(Treeprinting)。

将已在内存中的赫夫曼树以直观的方式(比如树)显示在终端上,同时将此字符形式的赫夫曼树写入文件TreePrint中。

2.测试要求

(1)已知某系统在通信联络中只可能出现八种字符,其频率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试设计赫夫曼编码。

(2)用下表给出的字符集和频度的实际统计数据建立赫夫曼树,并实现以下报文的编码和译码:

“THISPROGRAMEISMYFAVORITE”。

字符

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

3.实现提示

(1)编码结果以文本方式存储在文件Codefile中。

(2)用户界面可以设计为“菜单”方式:

显示上述功能符号,再加上“Q”,表示退出运行Quit。

请用户键入一个选择功能符。

此功能执行完毕后再显示此菜单,直至某次用户选择了“Q”为止。

(3)在程序的一次执行过程中,第一次执行I,D或C命令之后,赫夫曼树已经在内存了,不必再读入。

每次执行中不一定执行I命令,因为文件hfmTree可能早已建好。

#include

#include

#include

#include

typedefstruct{

charletter;

floatwt;

}hfm,*hfmlist;

//*************************全局变量************************************

unsignedints1,s2,n;

charchoose;

intDEPTH=0;

chara[20];

//***************Huffman树和Huffman编码的存储表示**********************

typedefstruct{

unsignedintweight;

unsignedintcode;

unsignedintparent,lchild,rchild;

}HTNode,*HuffmanTree;//动态分配数组存储Huffman树

typedefchar**HuffmanCode;//动态分配数组存储Huffman编码表

//***************************初始化Huffman树***************************

voidselect(HuffmanTreeHT,intl){

inta,b,c,j;

s1=s2=1;

a=b=1000;

for(j=1;j<=l;j++){

if(HT[j].code==0){

c=HT[j].weight;

if(c

elseif(c

}//if

}//for

HT[s1].code=HT[s2].code=1;

}//select

voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,hfmlistHL,unsignedintn){

//w存放n个权值(均>0),构造Huffman树HT,并求出n个字符的Huffman编码HC.

unsignedinti,f,start,c,m;

char*cd;

if(n<=1)return;

m=2*n-1;

HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));

for(i=1;i<=m;++i){HT[i].weight=HT[i].parent=HT[i].lchild=HT[i].rchild=HT[i].code=0;}

for(i=1;i<=n;++i)HT[i].weight=HL[i].wt;

for(i=n+1;i<=m;++i){

select(HT,i-1);

HT[s1].parent=i;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*));

cd=(char*)malloc(n*sizeof(char));

cd[n-1]='\0';

for(i=1;i<=n;++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';

elsecd[--start]='1';

HC[i]=(char*)malloc((n-start)*sizeof(char));

strcpy(HC[i],cd+start);

}

free(cd);

}

//*************************文件操作*****************************

voidsave(char*p){

FILE*fp;

inti;

printf("inputthename:

");

if((fp=fopen(gets(a),"w+"))==NULL){

printf("cannotopenthefile!

\n");

exit(0);}//if

for(i=0;p[i]!

='\0';i++){

if(fwrite(p+i,sizeof(char),1,fp)!

=1){//fwrite函数写数据块

printf("Filewriteerror!

\n");exit(0);}//if

}//for

fclose(fp);

}//save

//************************编码与译码操作**********************************

voidDecoding(HuffmanTreeHT,hfmlistHL,char*size,intn)//这个函数是用来译码的

{inti,j,k;

charp[130];

printf("请输入需要译码的代码:

");gets(p);//接受需要译码的字符串

i=2*n-1;

k=0;

for(j=0;p[j]!

='\0';j++){

if(p[j]=='0'){if(HT[i].lchild!

=0)i=HT[i].lchild;

else{size[k++]=HL[i].letter;

i=2*n-1;

j--;}

}

else{if(HT[i].rchild!

=0)i=HT[i].rchild;

else{size[k++]=HL[i].letter;

i=2*n-1;

j--;}

}

}//for

if(p[j-1]=='0')size[k++]=HL[i].letter;

elsesize[k++]=HL[i].letter;

size[k]='\0';

}//decoding

voidEncoding(HuffmanCodeHC,hfmlistHL,char*coding,intn){

inti,j,t,k=0;

charp[100];

printf("请再次输入需要编码的文本:

");

gets(p);

for(i=0;p[i]!

='\0';i++){

if((p[i]>='A'&&p[i]<='Z')||p[i]=='')

for(j=1;j<=n;j++)

if(p[i]==HL[j].letter)

for(t=0;HC[j][t]!

='\0';t++)

coding[k++]=HC[j][t];

}//for

coding[k]='\0';

}//encoding

//************************打印操作****************************

voidPrint(FILE*fp1,FILE*fp2){

//将文件fp1中的代码以紧凑格式显示在终端上,每行50个代码

//同时将此字符形式的编码文件写入文件fp2中

charc[200];

inti;

fgets(c,200,fp1);

for(i=0;c[i]=='0'||c[i]=='1';i++){

printf("%c",c[i]);

fprintf(fp2,"%c",c[i]);

if((i+1)/50*50==(i+1)){

printf("\n");

fprintf(fp2,"\n");

}

}//for

printf("\n");

}//Print

voidPreOrderTraverse(HuffmanTreeHT,intk,FILE*fp){

//先序遍历并打印树,结果存放于fp中,k为根结点的下标

inti;

for(i=1;i<=DEPTH-1;i++)fprintf(fp,"");

for(;i<=DEPTH;i++)fprintf(fp,"|------");

fprintf(fp,"%d\n",HT[k].weight);

if(HT[k].lchild!

=0){

DEPTH++;

PreOrderTraverse(HT,HT[k].lchild,fp);

DEPTH--;

}

if(HT[k].rchild!

=0){

DEPTH++;

PreOrderTraverse(HT,HT[k].rchild,fp);

DEPTH--;

}

if(HT[k].lchild==0&&HT[k].rchild==0)return;

return;

}//PreOrderTraverse

voidTreePrinting(HuffmanTreeHT,intn,FILE*fp){

//打印树HT,结果存于文件fp中,n为树的叶子结点数

inti,k;

for(i=1;i<=2*n;i++)if(HT[i].parent==0){k=i;bre

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

当前位置:首页 > 小学教育 > 语文

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

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