哈弗曼编码编译器.docx
- 文档编号:9932797
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:23
- 大小:240.88KB
哈弗曼编码编译器.docx
《哈弗曼编码编译器.docx》由会员分享,可在线阅读,更多相关《哈弗曼编码编译器.docx(23页珍藏版)》请在冰豆网上搜索。
哈弗曼编码编译器
哈尔滨理工大学
课 程 设 计
(数据结构)
题 目:
哈弗曼编码编译器
班 级:
姓 名:
指导教师:
系主任:
2013年03月08日
目录
1(自己的课程设计题目)问题课程设计1
1.1题目分析1
1.2数据结构1
1.3流程图1
1.4实现技术2
1.5设计结论和心得2
2(使用的程序语言,例如C或C++)代码分析3
2.1功能说明3
2.2局部数据结构3
2.3流程图3
2.4以实例说明运行过程4
1哈弗曼编码编译器设计报告
1.1题目分析
设计一个哈弗曼编码译码器,实现哈夫曼树的建立,树形输出,编码和解码。
1.2数据结构
#include
#include
#include
typedefstruct//结点的结构
{
unsignedintweight;//结点的权值
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;//动态分配数组存储哈夫曼树
typedefchar**HuffmanCode;//动态分配数组存储哈夫曼编码
HuffmanTreeHT;
HuffmanCodeHC;
intn=8;
constcharmenu[]=
"|1建立哈夫曼树|\n"
"|2查看哈夫曼编码|\n"
"|3树形输出哈夫曼树|\n"
"|4哈夫曼文件编码|\n"
"|5哈夫曼文件解码|\n"
"|6帮助|\n"
"|7退出系统|\n";
constcharhelpsabout[]=
"|主要功能:
|\n"
"|利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息的传输时间,降低|\n"
"|传输成本。
但是,这要求在发送端通过一个编码系统对待传输的数据预先编码,在接收|\n"
"|端将传来的数据进行译码(复原)。
对于双工信道,每端都要有一个完整的编/译码系|\n"
"|统。
本系统即是为这样的信息收发站写一个哈夫曼码的编/译系统。
|\n"
"||\n"
"||\n";
voidHuffmantree();
voidHuffmancode();
voidpreorder();
voidstringcopy();
intmin();
voidselect();
voiddecode();
voidencode();
voidint_huffmantree();
voidprint_end();
voidprint_title();
voidprint_menu();
voidprint_helpabout();
voidprint_huffmancode();
voidprint_tree();
//------------------先序遍历----------------------------------------------------
voidpreorder(introot,intdepth)
{
inti;
for(i=1;i<=depth;i++)
printf("");
if(depth!
=0)
printf("└");
else
printf("");
printf("%d",HT[root].weight,depth);
if(root<=n)
printf(":
%s\n",HC[root]);//依次输出哈夫曼编码
else
printf("\n");
if(HT[root].lchild!
=0)
{depth++;preorder(HT[root].lchild,depth);}
if(HT[root].rchild!
=0)
{preorder(HT[root].rchild,depth);}
}
//--------------字符串拷贝函数----------------------------------------------------
voidstringcopy(char*strDest,char*strSrc)
{
char*strDestCopy=strDest;
if(!
(strDest&&strSrc))
printf("ERROR!
");
while((*strDest++=*strSrc++)!
='\0');
}
//--------返回哈夫曼树t的前i个结点中权值最小的树的根结点序号,函数select()调用------------
intmin(HuffmanTreet,inti)
{
intj,m;
unsignedintk=0xffffffff;//k存最小权值,初值取为不小于可能的值
for(j=1;j<=i;j++)//对于前i个结点
if(t[j].weight {k=t[j].weight;//t[j]的权值赋给k m=j;//序号赋给m } t[m].parent=1;//给选中的根结点的双亲赋非零值,避免第2次查找该结点 returnm;//返回权值最小的根结点的序号 } //----在哈夫曼树t的前i个结点中选择2个权值最小的树的根结点序号,s1为其中序号(权值)较小的---- voidselect(HuffmanTreet,inti,int&s1,int&s2) { intj; s1=min(t,i);//权值最小的根结点序号 s2=min(t,i);//权值第2小的根结点序号 if(s1>s2)//s1的序号大于s2的 {//交换 j=s1; s1=s2;//s1是权值最小的2个中序号较小的 s2=j;//s2是权值最小的2个中序号较小的 } } //-------w存放n个字符的权值(均>0),构造哈夫曼树HT---------------------------------------- voidHuffmantree(int*w) { intm,i,s1,s2; HuffmanTreep; if(n<=1)//叶子结点数不大于n return; m=2*n-1;//n个叶子结点的哈夫曼树共有m个结点 HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用 for(p=HT+1,i=1;i<=n;++i,++p,++w)//从1号单元开始到n号单元,给叶子结点赋值 {//p的初值指向1号单元 (*p).weight=*w;//赋权值 (*p).parent=0;//双亲域为空(是根结点) (*p).lchild=0;//左右孩子为空(是叶子结点,即单结点树) (*p).rchild=0; } for(;i<=m;++i,++p)//i从n+1到m (*p).parent=0;//其余结点的双亲域初值为0 for(i=n+1;i<=m;++i)//建哈夫曼树 {//在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2 select(HT,i-1,s1,s2); HT[s1].parent=HT[s2].parent=i;//i号单元是s1和s2的双亲 HT[i].lchild=s1;//i号单元的左右孩子分别是s1和s2 HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight;//i号单元的权值是s1和s2的权值之和 } } //-------并求出n个字符的哈夫曼编码HC-------------------------------------------------- voidHuffmancode() { intstart; unsignedintf; inti; unsignedintc; char*cd; HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n个字符编码的头指针 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)//c是其双亲的左孩子 cd[--start]='0';//由叶子向根赋值'0' else//c是其双亲的右孩子 cd[--start]='1';//由叶子向根赋值'1' HC[i]=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间 stringcopy(HC[i],&cd[start]);//从cd复制编码串到HC矩阵 } free(cd);//释放工作空间 } //---------------------译码----------------------------------------------------- voidencode() { FILE*fp1=NULL,*fp2=NULL; charinput[20]="input.txt",output[20]="output.txt"; printf("请输入输入文件名(input.txt): "); scanf("%s",input); if((fp1=fopen(input,"r"))==NULL) { printf("无此文件! "); getchar(); getchar(); return; } printf("请输入输出文件名(output.txt): "); scanf("%s",output); if((fp2=fopen(output,"w"))==NULL) { printf("不能创建文件! "); getchar(); getchar(); return; } inti,k; unsignedint*w,p,m=0,j; for(k=0;! feof(fp1);k++) { if(fgetc(fp1)=='') m++; } printf("哈夫曼编码为: "); fp1=fopen(input,"r"); w=(unsignedint*)malloc(m*sizeof(unsignedint));//动态生成存放m个权值的空间 for(j=0;j<=m-1;j++) { fscanf(fp1,"%d",w+j);//依次输入原码 } for(p=0;p { for(i=0;i if(*(w+p)==HT[i+1].weight) { fprintf(fp2,"%s",HC[i+1]); printf("%s",HC[i+1]); } } fclose(fp1); fclose(fp2); printf("\n输出完成.按任意键继续...."); getchar(); getchar(); } //-------------------------解码------------------------------------------------- voiddecode() { FILE*fp1=NULL,*fp2=NULL; charinput[20],output[20]; char*code; code=(char*)malloc(n*sizeof(char)); printf("请输入输入文件名(input.txt): "); scanf("%s",input); if((fp1=fopen(input,"r"))==NULL) { printf("无此文件! "); getchar(); getchar(); return; } printf("请输入输出文件名(output.txt): "); scanf("%s",output); if((fp2=fopen(output,"w"))==NULL) { printf("不能创建文件! "); getchar(); getchar(); return; } inti,j; printf("哈夫曼译码为: "); for(i=0;! feof(fp1);i++) { *(code+i)=fgetc(fp1); *(code+i+1)='\0'; for(j=0;j if(strcmp(code,HC[j+1])==0) { fprintf(fp2,"%d",HT[j+1].weight); printf("%d",HT[j+1].weight); i=-1; break; } } fclose(fp1); fclose(fp2); printf("\n输出完成.按任意键继续...."); getchar(); getchar(); } //---------------------初始化哈夫曼树------------------------------------------ voidint_huffmantree() { system("cls"); print_title(); int*w,i; printf("请输入权值的个数(>1): "); scanf("%d",&n); w=(int*)malloc(n*sizeof(int));//动态生成存放n个权值的空间 printf("请依次输入%d个权值(整型): \n",n); for(i=0;i { scanf("%d",w+i); } Huffmantree(w);//根据w所存的n个权值构造哈夫曼树HT, Huffmancode();//n个哈夫曼编码存于HC print_end(); printf("哈夫曼编码为: \n"); for(i=1;i<=n;i++) printf("%5d: %s\n",*(w+i-1),HC[i]); print_end(); printf("按任意键返回..."); getchar(); getchar(); } //-----------------哈夫曼编码菜单---------------------------------- voidprint_huffmancode() { inti; system("cls"); print_title(); printf("哈夫曼编码为: \n"); for(i=1;i<=n;i++) printf("%5d: %s\n",HT[i].weight,HC[i]); print_end(); printf("按任意键返回..."); getchar(); getchar(); } //--------------帮助菜单------------------------------------------- voidprint_helpabout() { system("cls"); print_title(); printf(helpsabout); print_end(); printf("按任意键返回..."); getchar(); getchar(); } //----------------树形输出菜单-------------------------------------- voidprint_tree() { system("cls"); print_title(); printf("哈夫曼树为: \n"); preorder(2*n-1,0); print_end(); printf("按任意键返回..."); getchar(); getchar(); } //--------------------选择菜单输出------------------------------------------------- voidprint_menu() { while (1) { intselected=0; system("cls"); print_title(); printf(menu); print_end(); printf(">请选择[1~7]"); scanf("%d",&selected); if(selected<1||selected>7) { printf("错误的选择! (请输入1~7).按任意键继续...."); getchar(); getchar(); } switch(selected){ case1: int_huffmantree(); break; case2: print_huffmancode(); break; case3: print_tree(); break; case4: encode(); break; case5: decode(); break; case6: print_helpabout(); break; case7: exit(0); break; } } } voidprint_title() { printf("+=============================================================================+\n"); printf("|哈夫曼编码译码器|\n"); printf("|DesignedByOrganne|\n"); printf("+=============================================================================+\n"); } voidprint_end() { printf("+=============================================================================+\n"); } voidmain() { intw[8]={5,29,7,8,14,23,3,11}; Huffmantree(w);//根据w所存的n个权值构造哈夫曼树HT, Huffmancode();//n个哈夫曼编码存于HC system("color17"); print_title(); print_menu(); } 1.3流程图 ①主函数流程图: 1.4实现技术 开发工具: VISCALLc++6.0; 编程语言: C语言。 实现步骤如下: (1)主调函数 (2)建立HuffmanTree (3)生成Huffman编码并写入文件 (4)电文译码 运行结果如下: 注意: 此处应采用软件截图说明! ! ! 1.5设计结论和心得 在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。 这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试C程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。 在课程设计过程中,我们不但有自己的独立思考,还借助各种参考文献来帮助我们完成系统。 更为重要的是,我们同学之间加强了交流,在对问题的认识方面可以交换不同的意见。 数据结构课程具有比较强的理论性,同时也具有较强的可应用性和实践性。 课程设计是一个重要的教学环节。 我们在一般情况下都能够重视实验环节,但是容易忽略实验的总结,忽略实验报告的撰写。 通过这次实验让我们明白: 作为一名大学生必须严格训练分析总结能力、书面表达能力。 需要逐步培养书写科学实验报告以及科技论文的能力。 只有这样,我们的综合素质才会有好的提高。 忽略此处..
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈弗曼 编码 编译器