数据结构课程设计 哈弗曼编译.docx
- 文档编号:12709377
- 上传时间:2023-04-21
- 格式:DOCX
- 页数:40
- 大小:203.99KB
数据结构课程设计 哈弗曼编译.docx
《数据结构课程设计 哈弗曼编译.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计 哈弗曼编译.docx(40页珍藏版)》请在冰豆网上搜索。
数据结构课程设计哈弗曼编译
《数据结构》
课程设计报告
学院(系):
班级:
学生学号:
姓名:
指导教师:
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< 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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构课程设计 哈弗曼编译 数据结构 课程设计 哈弗曼 编译
![提示](https://static.bdocx.com/images/bang_tan.gif)