哈夫曼编码译码系统(共16页).doc
《哈夫曼编码译码系统(共16页).doc》由会员分享,可在线阅读,更多相关《哈夫曼编码译码系统(共16页).doc(16页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上 数据结构 课程设计赫夫曼编码/译码器设计指导教师:孙树森、周维达班级:09数媒(2)班学号:E姓名:曾焕凯专心-专注-专业 数据结构课程设计报告书1、 实验目的1、提高分析问题、解决问题的能力,进一步巩固数据结构各种原理与方法。2、熟悉掌握一门计算机语言,可以进行数据算法的设计。二、实验原理1、 哈夫曼树的定义: 假设有 n 个权值,试构造一颗有 n 个叶子节点的二叉树,每个叶子带 权值为 wi,其中树带权路径最小的二叉树成为哈夫曼树或者最优二叉树; 2、 哈夫曼树的构造: weight 为输入的频率数组,把其中的值赋给依次建立的 HT Node 对象中的 data
2、 属性, 即每一个 HT Node 对应一个输入的频率。然后根据 data 属性按从小到大顺序排序,每次从 data 取出两个最小和此次小的 HT Node,将他们的 data 相加,构造出新的 HTNode 作为 他们的父节点,指针 parent,leftchild,rightchild 赋相应值。在把这个新的节点插入最小堆。 按此步骤可以构造构造出一棵哈夫曼树。 通过已经构造出的哈夫曼树,自底向上,由频率节点开始向上寻找 parent,直到 parent 为树的顶点为止。这样,根据每次向上搜索后,原节点为父节点的左孩子还是右孩子,来记 录 1 或 0,这样,每个频率都会有一个 01 编码与
3、之唯一对应,并且任何编码没有前部分是 同其他完整编码一样的。3、 实验步骤先统计要压缩编码的文件中的字符字母出现的次数,按字符字母和空格出现的概率对其进行哈夫曼编码。然后读入要编码的文件,编码后存入另一个文件;接着再调出编码后的文 件,并对其进行译码输出,最后存入另一个文件中。具体步骤:1. 初始化,统计文本文件中各字符的个数作为权值,生成哈夫曼树; 2. 根据符号概率的大小按由大到小顺序对符号进行排序;3. 把概率最小的两个符号组成一个节点; 4. 重复步骤2. 3 ,直到概率和为 1;5. 从根节点开始到相应于每个符号的“树叶”,概率大的标“0”,概率小的标“1”; 6. 从根节点开始,对
4、符号进行编码; 7. 译码时流程逆向进行,从文件中读出哈夫曼树,并利用哈夫曼树将编码序列解码。四、实验结果与分析哈夫曼编码是动态变长编码,临时建立概率统计表和编码树。概率小的码比较长,概率 小的码比较长。概率大的码短,这样把一篇文件编码后,就会压缩许多。从树的角度看,哈夫曼编码方式是尽量把短码都利用上。首先,把一阶节点全都用上, 如果码字不够时, 然后, 再从某个节点伸出若干枝,引出二阶节点作为码字,以此类推,显然所得码长最短,再根据 建立的概率统计表合理分布和放置,使其平均码长最短就可以得到最佳码。实验截图:五、实验心得本次实验结合了之前所学的赫夫曼算法,并利用其原理实现赫夫曼编码/译码系统
5、;实验难度较之前的几次实验有所增加,所以花了比较多的时间来编写,测试代码。期间参考了网上的一些程序,通过结合分析,了解其他人在实现这个算法时的思想,也借鉴了其中的一些东西,同时加入了自己的想法。最终完成饿了本次的作业。通过这次实验,我了解了一个算法到一个可以执行的程序之间还有很多工作需要做,深刻体会到实践出真知的到了,看似简单的算法在实现时却话费了这么多时间,但是这个过程中也让我学到了很多。六、主要代码Huffman_Tree.h:#ifndef Huffman_Tree_h#define Huffman_Tree_h#endif#include typedef struct unsigned
6、 int weight; unsigned int parent,lchild,rchild;HTNode, * HuffmanTree; /存储赫夫曼树的结点类型typedef char * * HuffmanCode; /用于存储字符集中各个字符相应的赫夫曼编码void strcpy(char *S1,char *S2) /将字符串S2复制到S1 int i = 0; while( S2i != 0 ) S1i = S2i; i+; S1i = 0;/在HT1到HTt-1中找出权值最小的两个S1和S2-void Select(HuffmanTree HT,int t,int &s1,int
7、 &s2) int i = 1; s1 = s2 = 0; HT0.weight = 50000; while( i = t ) /遍历查找权值最小的结点S1 if( HTi.parent = 0 & HTi.weight HTs1.weight ) s1 = i; i+; i = 1; while( i = t ) /遍历查找除S1外权值最小的结点S2 if( i != s1 & HTi.parent = 0 & HTi.weight HTs2.weight ) s2 = i; i+; /根据各个字符的权值构造赫夫曼树HT,将对应的赫夫曼编码存储在HC中-int HuffmanCoding(
8、 HuffmanTree &HT,HuffmanCode &HC,int *w,int n) int s1,s2,m,i,start; unsigned int c,f; HTNode * p; char *cd; if( n = 1 ) return 0; m = 2 * n - 1; /赫夫曼树的总结点树为m HT = (HuffmanTree)malloc(m + 1) * sizeof(HTNode); /申请存储赫夫曼树的空间 for(p = HT + 1, i = 1; i weight = *(w+1); p-parent = p-lchild = p-rchild = 0; f
9、or( ; i weight = p-parent = p-lchild = p-rchild = 0; for( i = n + 1; i = m; +i ) /构造赫夫曼树,给各个非叶子结点赋值 Select(HT, i - 1, s1, s2); HTs1.parent = i; HTs2.parent = i; HTi.lchild = s1; HTi.rchild = s2; HTi.weight = HTs1.weight + HTs2.weight; /根据已建立的赫夫曼树对需要编码的字符进行编码- HC = (HuffmanCode)malloc(n + 1) * sizeof
10、(char *); /用于存储指向存储各个字符相应赫夫曼编码的字符数组的指针 cd = (char *)malloc(n * sizeof(char); /分配工作所需空间 cdn - 1 = 0; /编码结束符 for( i = 1; i = n; +i) /逐个字符求赫夫曼编码 start = n -1; /编码在数组cd中的最前位置 /从叶子到根逆向求编码,初始值;停止条件;一次循环后对上一个节点做循环 for(c = i,f = HTi.parent; f != 0; c = f, f = HTf.parent) if(HTf.lchild = c) cd -start = 0; el
11、se cd -start = 1; HCi = (char *)malloc(n - start)*sizeof(char); /为第i个字符编码分配空间 strcpy(HCi, &cdstart); /将cd数组的start位置到n-1位置复制给HCi free(cd); /释放空间 return 1;Test.cpp:#include #include #include Huffman_Tree.h#define Yes 1 /当程序已经调用过初始化赫夫曼树的InitHuff_T()函数,或已从htfTree文件读取过,则将Init_Mode置为Yes,否则为No#define No 0v
12、oid InitHuff_T( HuffmanTree &HT, HuffmanCode &HC, char ch,int &n ) /初始化赫夫曼数,要求用户输入字符和相应权值 int i = 1,w100,temp,j; char a20; /数字转字符时,用于储存赫夫曼编码 FILE *save; printf(请输入编码字符集的大小:); scanf(%d,&n); /获取用户输入的字符集个数 while( i = n ) /获取用户输入的字符和相应权值,分别存储在ch和w数组中 printf(请输入第%d个字符和该字符的权值:,i); fflush(stdin); /刷新标准输入缓冲
13、区,把输入缓冲区里的东西丢弃 scanf(%c%d,&chi,&wi); i+; chi = 0; /哈夫曼树保存- HuffmanCoding(HT,HC,w,n); /根据用户的输入,生成赫夫曼数及各个字符相应的赫夫曼编码,分别存在HT树和HC中 if( save = fopen(hfmTree.TXT,w) = NULL ) /打开用于存储赫夫曼树的文件 printf(Open file fail.n); exit(0); temp = n; /将字符集大小转换成字符形式写入到文件hfmTree.TXT中 j = 0; while( temp != 0 )/计算数字位数 temp = t
14、emp / 10; j+; temp = n; /数字转字符 aj = 0; while( temp != 0 ) aj - 1 = (char)(temp % 10 + 48); temp = temp / 10; j-; fputs(a,save); printf(%dn,n); /向屏幕输出字符集大小n fputc(n,save); /换行 for( i = 1; i = n; i+ ) /分别向文件和屏幕输出各个字符和相应的赫夫曼编码 fputc(chi,save); printf(%ct,chi); /字符 fputc(t,save); fputs(HCi,save); printf
15、(%sn,HCi); /编码 fputc(n,save); for(i = 1; i = 2 * n - 1; i+ ) /将赫夫曼树各个结点的parent,lchild,rchild分别写入到文件中 temp = HTi.parent; /将i结点的parent转换成字符并写入到文件中 if(temp = 0) fputc(temp + 48,save); fputc( ,save); else j = 0; /计算HTi.parent数字位数 while( temp != 0 ) temp = temp / 10; j+; temp = HTi.parent; /数字转字符 aj = 0;
16、 while( temp != 0 ) aj - 1 = (char)(temp % 10 + 48); temp = temp / 10; j-; fputs(a,save); fputc( ,save); temp = HTi.lchild; /将i结点的lchild转换成字符并写入到文件中 if(temp = 0) fputc(temp + 48,save); fputc( ,save); else j = 0; /计算HTi.lchild数字位数 while( temp != 0 ) temp = temp / 10; j+; temp = HTi.lchild; /数字转字符 aj
17、= 0; while( temp != 0 ) aj - 1 = (char)(temp % 10 + 48); temp = temp / 10; j-; fputs(a,save); fputc( ,save); temp = HTi.rchild; /将i结点的rchild转换成字符并写入到文件中 if(temp = 0) fputc(temp + 48,save); fputc(n,save); else j = 0; /计算HTi.lchild数字位数 while( temp != 0 ) temp = temp / 10; j+; temp = HTi.rchild; /数字转字符
18、 aj = 0; while( temp != 0 ) aj - 1 = (char)(temp % 10 + 48); temp = temp / 10; j-; fputs(a,save); fputc(n,save); fclose(save);/编码,并将所得编码存储到文件-void Encoding(HuffmanTree &HT, HuffmanCode &HC, char ch) FILE *ToBeTran,*CodeFile; int i; char c; if( ToBeTran = fopen(ToBeTran.TXT,r) = NULL ) printf(Open fi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈夫曼 编码 译码 系统 16
限制150内