数据结构 课程设计之哈夫曼编码.doc

上传人:sk****8 文档编号:3102073 上传时间:2019-05-21 格式:DOC 页数:9 大小:231KB
下载 相关 举报
数据结构  课程设计之哈夫曼编码.doc_第1页
第1页 / 共9页
数据结构  课程设计之哈夫曼编码.doc_第2页
第2页 / 共9页
数据结构  课程设计之哈夫曼编码.doc_第3页
第3页 / 共9页
数据结构  课程设计之哈夫曼编码.doc_第4页
第4页 / 共9页
数据结构  课程设计之哈夫曼编码.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

1、哈夫曼编码与解码的实现- 1 -一、设计思想(一) 哈夫曼树的设计思想对于一组具有确定权值的叶子结点可以构造出多个具有不同带权路径长度的二叉树,其中具有最小带权路径长度的二叉树称作哈夫曼树或最优二叉树。首先给定 n 个权值制造 n 个只含根结点的二叉树,得到一个二叉树林;再在这二叉树林里面找根结点的权值最小和次小的两棵树作成新的二叉树,其中新的二叉树的根结点的权值为左右子根结点权值之和;最后在二叉树林中把组合过的二叉树删除,再重复第二步,直到最后就剩一颗二叉树的时候得到的这棵二叉树就是哈夫曼树。(二)哈夫曼编码与解码的设计思想在数据通讯中,经常要将传送的文字转换为二进制字符 0 和 1 组成的

2、二进制串,称这个过程为编码。与子相对的是解码或是译码,就是用与编码相同的方式将二进制串转换称编码前的文字的过程称作解码。在这里是通过哈夫曼树实现编码与解码的,所以称作是哈夫曼编码与解码。首先输入一个字符串,还有相应的在哈夫曼树里的权值,这样用哈夫曼树把字符串用二进制串代替它,这个过程要注意树和编码问题,其中树的问题在上面已经解决,主要看编码的问题,就是根据我们输入的字符串和权值建立相应的树模型,这一步完成那编码就已经完成了,最后打印就行了;然后就是解码,完成编码相应的解码就相对简单了,就是先找到在编码的时候建的那个模型树,将编码中的二进制串再根据权值转换为相应的字符串,这样一步步解码就行了。以

3、上就是通过用哈夫曼树进行哈夫曼编码与解码如何实现的主要设计思想。哈夫曼编码与解码的实现- 2 -二、算法流程图(一)哈夫曼树的流程图开始初始化哈夫曼链表二叉树林找最小和次小的二叉树组合成新的二叉树删除用过的二叉树是不是最后一个二叉树结束是不是图 1 哈夫曼树的流程图(二)编码与解码的流程图开始输入字符串判断权值建立路径有最小和次小循环建立二叉树根据树对路径分左 0 右 1写出对应结点的编码结束开始找到树的根结点输入二进制串扫描根据树的路径打印对应字符继续扫描是否结束否输出字符串是结束图 2 编码与解码的流程图图片说明:(左边)编码流程图, (右边)解码流程图。哈夫曼编码与解码的实现- 3 -三

4、、源代码下面给出的是用中缀转后缀算法实现的程序的源代码:#include “stdio.h“#include “string.h“#define MAX 100 /*定义常量*/struct HaffNodeint weight; /*权值*/int parent; /*双亲结点下标*/char ch;int lchild;int rchild;*myHaffTree; /*构造哈夫曼树*/struct Codingchar bitMAX; /*定义数组*/char ch;int weight; /*字符的权值*/*myHaffCode; /*定义结构体*/void Haffman(int n

5、) /*定义哈夫曼函数*/int i,j,x1,x2,s1,s2;for (i=n+1;i=2*n-1;i+) /*树的初始化*/s1=s2=10000;x1=x2=0;for (j=1;j=i-1;j+) /*构造哈夫曼树的非叶子结点*/if(myHaffTreej.parent=0x2=x1;s1=myHaffTreej.weight;x1=j;else if(myHaffTreej.parent=0x2=j;myHaffTreex1.parent=i;myHaffTreex2.parent=i;myHaffTreei.weight=s1+s2; /*左右子组合为新树*/myHaffTre

6、ei.lchild=x1;myHaffTreei.rchild=x2;哈夫曼编码与解码的实现- 4 -void HaffmanCode(int n) /*构造 n 个结点哈夫曼编码*/int start,c,f,i,j,k;char *cd;cd=(char *)malloc(n*sizeof(char);myHaffCode=(struct Coding *)malloc(n+1)*sizeof(struct Coding);cdn-1=0;for(i=1;i=n;+i) /*n 个叶子结点的哈夫曼编码*/start=n-1;for(c=i,f=myHaffTreei.parent;f!=0

7、;c=f,f=myHaffTreef.parent)if(myHaffTreef.lchild=c) cd-start=0;else cd-start=1;for(j=start,k=0;jn;j+)myHaffCodei.bitk=cdj;k+;myHaffCodei.ch=myHaffTreei.ch; /*取编码对应的权值*/myHaffCodei.weight=myHaffTreei.weight;free(cd);Init() /*定义有返回值的函数*/int i,n,m;printf(“please input the number of words:“);scanf(“%d“,m

8、=2*n-1;myHaffTree=(struct HaffNode *)malloc(sizeof(struct HaffNode)*(m+1);for(i=1;i=n;i+)printf(“please input the word and the equal:“);scanf(“%s%d“,myHaffTreei.parent=0;myHaffTreei.lchild=0;myHaffTreei.rchild=0;for(i=n+1;i=m;i+)myHaffTreei.ch =#;myHaffTreei.lchild=0;哈夫曼编码与解码的实现- 5 -myHaffTreei.pare

9、nt=0;myHaffTreei.rchild=0;myHaffTreei.weight=0;Haffman(n);HaffmanCode(n);for(i=1;i=n;i+)printf(“%c %d“,myHaffCodei.ch,myHaffCodei.weight);printf(“n“);printf(“init success!n“);return n;void Caozuo_C(int m) /* 编码函数 */int n,i,j;char string50,*p;printf(“please input the words:“);scanf(“%s“,string);n=str

10、len(string); /*计算字符串长度*/for(i=1,p=string;i=n;i+,p+) /*进行编码*/for(j=1;j=m;j+)if(myHaffCodej.ch=*p)printf(“%sn“,myHaffCodej.bit);void Caozuo_D(int n) /*解码函数*/int i,c;char code1000,*p;printf(“please input the coding:“); /*输入二进制编码*/scanf(“%s“,code);for(p=code,c=2*n-1;*p!=0;p+) /*进行解码*/if(*p=0) /*结束条件*/c=

11、myHaffTreec.lchild; /*赋值*/if(myHaffTreec.lchild=0) /* 扫描*/printf(“%c“,myHaffTreec.ch);c=2*n-1;continue; /*结束*/哈夫曼编码与解码的实现- 6 -else if(*p=1)c=myHaffTreec.rchild;if(myHaffTreec.lchild=0)printf(“%c“,myHaffTreec.ch);c=2*n-1; /*赋值*/continue;printf(“n“);void main() /*主函数*/int n;char char1; /*定义字符*/n=Init(

12、); /*函数的调用*/printf(“A.coding B.codeprinting C.exitnplease input the process:n“);while(1)scanf(“%c“,if(char1=c) /*判断字符*/break;switch(char1)caseA:Caozuo_C(n);break; /*执行编码操作*/ caseB:Caozuo_D(n);break; /*执行解码操作*/caseC:;break; 哈夫曼编码与解码的实现- 7 -四、运行结果(一)中缀转后缀算法的运行结果:五、遇到的问题及解决这部分我主要遇到了如下三个问题,其内容与解决方法如下所列:

13、 问题 1: 刚开始不知道如何建一个好树,因为我开始试着建了几个二叉树,不知道什么原因运行的时候那编码总是不对,跟在草稿纸上自己画的那个二叉树总是不相符,就找原因。哈夫曼编码与解码的实现- 8 -解决方法: 开始时总是编码出错,就试着找错,树的初始化不可能出错,所以首先看那叶子结点的 for 函数,没什么错误,接着看非叶子结点的 for 函数,非叶子结点不好弄,找起来麻烦一些,就是费时间,盘查到最后也没什么错,最后就是左右子结点重生结点的一块了,这也比较好查,可是结果却是错处在这儿了,没想到最放心的一块出了错,得好好反省反省了,以后绝不能在这些问题上出错了,还好不是很严重,还可以补回来。 问题

14、 2: 由于前一个问题的解决,后面小心意义的写,尽量放慢写的速度,省的再花时间找错,可是最后能运行,运行的结果却是错的不容乐观啊,还出现一些不认识的乱码,这样的问题最难了,也是最不想遇到的问题,逻辑问题和一些代码输入有误。解决方法: 刚开始改的时候不知哪儿错,就是乱改一通,结果还是找不到哪儿出错了,只能请高手了,不过还是问了两个人才解决这个问题的。最后还是不是怎么懂,马马虎虎吧。 问题 3:这个问题是写到前面才想起来的,就是哈夫曼编码与解码这个作业的原理不是很懂,刚开始在课上听的就不是很懂很透,结果过了两天忘了。解决方法:这个问题跟别人讨论了一下,然后给我讲了一下就懂了,也没什么难的,就这么轻

15、松的解决了。六、心得体会通过这次的作业我充分的认识到了自己的不足,特别是对写程序代码这方面,一个程序从算法到用程序把它实现出来,这一整个过程是很不容易的,你懂得它的算法,不一定就能写的出来,通过这次我也深深的了这一点。对于一个新手来说,小的错误出现的太多,而且一个小的错误就能让我束手无策,因为想不通错在哪,所以就一直在乱改,逻辑错误就更难了,有时候程序运行语法没有错误,但只要输入表达式计算结果时,出来的结果要不是错的,要不就不出现结果,这种错的原因更难找。感觉难的原因可能就是平时少练习,代码量也是积累很少的,这样我们寻找程序的错误觉得很难,修改过来就更难了。但是运行的正确结果出来的时候,觉得有点兴奋。不管怎么说,这次的作业给我的感触的确不小,懂得发现问题,尝试着从个方面收集资料努力去解决它,提升了自己解决问题的能力,但突然发现自己原来什么都不会,有的也是理论上懂得一点,但实践起来却无法下手,所以哈夫曼编码与解码的实现- 9 -觉得自己以后要学的东西实在是太多了,必须多动手才能克服这些低级错误。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育教学资料库 > 精品笔记

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。