数据结构课程设计 哈弗曼编译.docx

上传人:b****5 文档编号:12709377 上传时间:2023-04-21 格式:DOCX 页数:40 大小:203.99KB
下载 相关 举报
数据结构课程设计 哈弗曼编译.docx_第1页
第1页 / 共40页
数据结构课程设计 哈弗曼编译.docx_第2页
第2页 / 共40页
数据结构课程设计 哈弗曼编译.docx_第3页
第3页 / 共40页
数据结构课程设计 哈弗曼编译.docx_第4页
第4页 / 共40页
数据结构课程设计 哈弗曼编译.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

数据结构课程设计 哈弗曼编译.docx

《数据结构课程设计 哈弗曼编译.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计 哈弗曼编译.docx(40页珍藏版)》请在冰豆网上搜索。

数据结构课程设计 哈弗曼编译.docx

数据结构课程设计哈弗曼编译

《数据结构》

课程设计报告

学院(系):

班级:

学生学号:

姓名:

指导教师:

2012年6月17日

 

一、需求分析………………………………………………………3

二、概要设计………………………………………………………3

设计分析……………………………………………………………3

流程图………………………………………………………………3

三、详细设计……………………………………………………3

四、调试分析……………………………………………………12

五、用户手册……………………………………………………13

六、测试结果………………………………………………………13

运行过程……………………………………………………………13

运行结果……………………………………………………………17

七、设计心得………………………………………………………18

八、附录……………………………………………………………18

参考文献……………………………………………………………18

代码…………………………………………………………………19

一、需求分析

哈夫曼树,又称最优树,是一类带权路径长度最短的树,有着广泛的应用。

利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。

但是,这要求在发送端将传来的数据进行译码(复原),对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。

本程序将为这样的信息收发站写一个哈夫曼的编译码系统。

二、概要设计

本系统将由如下模块组成:

1、定义。

2、I:

初始化(Initialization)函数

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

3、E:

编码(Encoding)函数

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

4、D:

译码(Decoding)函数

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

5、P:

打印代码文件(Print)函数。

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

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

6、T:

打印哈夫曼树(TreePrinting).

将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrinting.

7、函数调用图如下:

Main

InitializationEncodingDecodingPrintTreePrint

SelectInputCodeCodepriningCoprint

Min

(main调用第二行所有函数,其余列的首字母对应的上一行函数调用下一行函数。

三、详细设计

哈夫曼编码是一种编码方式,它是根据每一个字符出现的概率而建立起来的。

哈夫曼编码借助树形结构构造,算法实现时使用链表或静态链表结构,空间的每个结点内有左子树、右子树、双亲指针。

在构成哈夫曼树之后,为求编码需从叶子结点出发走一条从叶子到根的路径;而为译码需从根出发走一条从根到叶子的路径。

要实现如上概要所说功能,需要进行如下步骤。

1、哈夫曼树及哈夫曼编码的存储表示

typedefstruct

{intweight;

intparent,lchild,rchild;

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

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

2、初始化

HuffmanTreeHT;

HuffmanCodeHC;

int*w,i,j;

constintn=26;

char*z;

intflag=0;

intnumb=0;

3、定义min功能函数

intmin(HuffmanTreet,inti)

{intj,flag;

intk=UINT_MAX;

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

if(t[j].weight

k=t[j].weight,flag=j;

t[flag].parent=1;

returnflag;}

4、定义选择权值最小的结点的函数

voidselect(HuffmanTreet,inti,int&s1,int&s2)

{intj;

s1=min(t,i);

s2=min(t,i);

if(s1>s2)

{j=s1;s1=s2;s2=j;}

}

5、编写求哈夫曼编码的算法。

voidHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*w,intn)

{intm,i,s1,s2,start;

intc,f;HuffmanTreep;

char*cd;if(n<=1)

return;

m=2*n-1;

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

for(p=HT+1,i=1;i<=n;++i,++p,++w)

{p->weight=*w;

p->parent=0;

p->lchild=0;p->rchild=0;}

for(;i<=m;++i,++p)

p->parent=0;

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

{select(HT,i-1,s1,s2);

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*));

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);}

6、在“我的课程设计”文件夹中新建“abc.txt”文件,文件内容如下:

字符

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

7、编写初始化(Initialization)函数

voidInitialization()

{flag=1;intnum2;

cout<<"下面初始化哈夫曼链表"<

w=(int*)malloc(n*sizeof(int));

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

cout<<"\n依次显示"<

charbase[2];

ifstreamfin("abc.txt");

for(i=0;i

{fin>>base;

*(z+i)=*base;

fin>>num2;

*(w+i)=num2;}

HuffmanCoding(HT,HC,w,n);

cout<<"字符"<

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

{

cout<

cout<

}

cout<<"下面将哈夫曼编码写入文件"<

FILE*htmTree;

charr[]={'','\0'};

if((htmTree=fopen("htmTree.txt","w"))==NULL)

{cout<<"不能打开文件"<

return;}

for(i=0;i

{fputc(*(z+i),htmTree);

fputs(r,htmTree);

}

for(i=0;i

{fprintf(htmTree,"%6d",*(w+i));

fputs(r,htmTree);

}

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

{fputs(HC[i],htmTree);

fputs(r,htmTree);}

fclose(htmTree);

cout<<"已将字符与对应编码写入根目录下文件htmTree.txt中"<

}

8、编写编码(Encoding)函数

voidInputCode()

{FILE*tobetran;

charstr[100];

if((tobetran=fopen("tobetran.txt","w"))==NULL)

{cout<<"不能打开文件"<

cout<<"请输入你想要编码的字符"<

gets(str);

fputs(str,tobetran);

cout<<"获取报文成功"<

fclose(tobetran);

cout<<"...................."<

voidEncoding()

{cout<<"下面对目录下文件tobetran.txt中的字符进行编码"<

FILE*tobetran,*codefile;

if((tobetran=fopen("tobetran.txt","rb"))==NULL)

{cout<<"不能打开文件"<

if((codefile=fopen("codefile.txt","wb"))==NULL)

{cout<<"不能打开文件"<

char*tran;

i=99;

tran=(char*)malloc(100*sizeof(char));

while(i==99)

{if(fgets(tran,100,tobetran)==NULL)

{cout<<"不能打开文件"<

for(i=0;*(tran+i)!

='\0';i++)

{for(j=0;j<=n;j++)

{if(*(z+j-1)==*(tran+i))

{fputs(HC[j],codefile);

if(j>n)

{cout<<"字符错误,无法编码!

"<

}

}

}

}

}

cout<<"…………编码完成…………"<

cout<<"编码写入目录下的codefile.txt中"<

fclose(tobetran);

fclose(codefile);

free(tran);

}

9、编写译码(Decoding)函数

voidDecoding()

{

cout<<"下面对根目录下文件codefile.txt中的字符进行译码"<

FILE*codef,*txtfile;

if((txtfile=fopen("\\Textfile.txt","w"))==NULL)

{cout<<"不能打开文件"<

}

txtfile=fopen("Textfile.txt","w");

if((codef=fopen("codefile.txt","r"))==NULL)

{cout<<"不能打开文件"<

codef=fopen("codefile.txt","r");

char*work,*work2,i2;

inti4=0,i,i3;

unsignedlonglength=10000;

work=(char*)malloc(length*sizeof(char));

fgets(work,length,codef);

work2=(char*)malloc(length*sizeof(char));

i3=2*n-1;

for(i=0;*(work+i-1)!

='\0';i++)

{i2=*(work+i);

if(HT[i3].lchild==0)

{*(work2+i4)=*(z+i3-1);

i4++;

i3=2*n-1;

i--;}

elseif(i2=='0')i3=HT[i3].lchild;

elseif(i2=='1')i3=HT[i3].rchild;

}

*(work2+i4)='\0';

fputs(work2,txtfile);

cout<<"…………译码完成…………"<

cout<<"内容写入根目录下的文件textfile.txt中"<

free(work);

free(work2);

fclose(txtfile);

fclose(codef);}

10.编写打印代码文件函数(Print)

voidCode_printing()

{cout<<"下面打印根目录下文件CodePrin.txt中编码字符"<

FILE*CodePrin,*codefile;

if((CodePrin=fopen("CodePrin.txt","w"))==NULL)

{cout<<"不能打开文件"<

return;}

if((codefile=fopen("codefile.txt","r"))==NULL)

{cout<<"不能打开文件"<

char*work3;

work3=(char*)malloc(51*sizeof(char));

if(fgets(work3,51,codefile)==NULL)

{cout<<"不能读取文件"<

elsedo

{

fputs(work3,CodePrin);

puts(work3);

}

while(strlen(work3)==50&&fgets(work3,51,codefile)!

=NULL);

free(work3);

cout<<"打印结束"<

}

11、编写打印哈夫曼树(TreePrinting)函数

voidcoprint(HuffmanTreestart,HuffmanTreeHT)

{if(start!

=HT)

{FILE*TreePrint;

if((TreePrint=fopen("TreePrint.txt","a"))==NULL)

{cout<<"创建文件失败"<

return;

}

numb++;

coprint(HT+start->rchild,HT);

cout<weight<

fprintf(TreePrint,"%d\n",start->weight);

coprint(HT+start->lchild,HT);

numb--;

fclose(TreePrint);

}

}

voidTree_printing(HuffmanTreeHT,intw){HuffmanTreep;p=HT+w;

cout<<"下面打印哈夫曼树"<

cout<<"打印工作结束"<

12、编写主函数

voidmain()

{cout<

cout<<"此程序实现哈夫曼编码解码功能"<

charchoice;

while(choice!

='q')

{cout<<"\n******************************"<

cout<<"哈夫曼编码解码"<

cout<<"******************************"<

cout<<"(i)初始化哈夫曼表"<

cout<<"(w)输入待编码的字符"<

cout<<"(e)进行编码、译码、打印编码"<

cout<<"(t)打印哈夫曼树"<

cout<<"(q)离开"<

if(flag==0)

{cout<<"\n请先初始化哈夫曼链表,输入'i'"<

cout<<"(程序将从根目录下的abc.txt文件中读出26个字母及其权值并对字母进行编码)"<

}

cin>>choice;

switch(choice)

{case'i':

Initialization();

break;

case'w':

InputCode();

break;

case'e':

Inputcoding();

Decoding();

Code_printing();

break;

case't':

Tree_printing(HT,2*n-1);

break;

case'q':

break;

default:

cout<<"输入命令错误"<

}

}

free(z);

free(w);

free(HT);

}

四、调试分析

调试过程是漫长而磨人的,以下截取少数错误以供参考:

Compiling...

aa.cpp

E:

\我的课程设计\课程设计\aa.cpp(39):

errorC2065:

'm':

undeclaredidentifier

E:

\我的课程设计\课程设计\aa.cpp(41):

errorC2065:

'p':

undeclaredidentifier

E:

\我的课程设计\课程设计\aa.cpp(41):

errorC2440:

'=':

cannotconvertfrom'HTNode*'to'int'

Thisconversionrequiresareinterpret_cast,aC-stylecastorfunction-stylecast

E:

\我的课程设计\课程设计\aa.cpp(42):

errorC2227:

leftof'->weight'mustpointtoclass/struct/union

E:

\我的课程设计\课程设计\aa.cpp(43):

errorC2227:

leftof'->parent'mustpointtoclass/struct/union

E:

\我的课程设计\课程设计\aa.cpp(44):

errorC2227:

leftof'->lchild'mustpointtoclass/struct/union

E:

\我的课程设计\课程设计\aa.cpp(44):

errorC2227:

leftof'->rchild'mustpointtoclass/struct/union

E:

\我的课程设计\课程设计\aa.cpp(46):

errorC2227:

leftof'->parent'mustpointtoclass/struct/union

E:

\我的课程设计\课程设计\aa.cpp(48):

errorC2065:

's1':

undeclaredidentifier

E:

\我的课程设计\课程设计\aa.cpp(48):

errorC2065:

's2':

undeclaredidentifier

E:

\我的课程设计\课程设计\aa.cpp(55):

errorC2065:

'cd':

undeclaredidentifier

E:

\我的课程设计\课程设计\aa.cpp(55):

errorC2440:

'=':

cannotconvertfrom'char*'to'int'

Thisconversionrequiresareinterpret_cast,aC-stylecastorfunction-stylecast

E:

\我的课程设计\课程设计\aa.cpp(56):

errorC2109:

subscriptrequiresarrayorpointertype

E:

\我的课程设计\课程设计\aa.cpp(56):

errorC2106:

'=':

leftoperandmustbel-value

E:

\我的课程设计\课程设计\aa.cpp(59):

errorC2065:

'start':

undeclaredidentifier

E:

\我的课程设计\课程设计\aa.cpp(60):

errorC2065:

'c':

undeclaredidentifier

E:

\我的课程设计\课程设计\aa.cpp(60):

errorC2065:

'f':

undeclaredidentifier

E:

\我的课程设计\课程设计\aa.cpp(63):

errorC2109:

subscriptrequiresarrayorpointertype

E:

\我的课程设计\课程设计\aa.cpp(63):

errorC2106:

'=':

leftoperandmustbel-value

E:

\我的课程设计\课程设计\aa.cpp(6

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

当前位置:首页 > 总结汇报 > 学习总结

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

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