哈夫曼编码译码系统.docx
- 文档编号:2100770
- 上传时间:2022-10-26
- 格式:DOCX
- 页数:20
- 大小:141.41KB
哈夫曼编码译码系统.docx
《哈夫曼编码译码系统.docx》由会员分享,可在线阅读,更多相关《哈夫曼编码译码系统.docx(20页珍藏版)》请在冰豆网上搜索。
哈夫曼编码译码系统
《数据结构》课程设计
——赫夫曼编码/译码器设计
指导教师:
孙树森、周维达
班级:
09数媒
(2)班
学号:
E09700227
姓名:
曾焕凯
数据结构课程设计报告书
1、实验目的
1、提高分析问题、解决问题的能力,进一步巩固数据结构各种原理与方法。
2、熟悉掌握一门计算机语言,可以进行数据算法的设计。
二、实验原理
1、哈夫曼树的定义:
假设有n个权值,试构造一颗有n个叶子节点的二叉树,每个叶子带权值为wi,其中树带权路径最小的二叉树成为哈夫曼树或者最优二叉树;
2、哈夫曼树的构造:
weight为输入的频率数组,把其中的值赋给依次建立的HTNode对象中的data属性,即每一个HTNode对应一个输入的频率。
然后根据data属性按从小到大顺序排序,每次从data取出两个最小和此次小的HTNode,将他们的data相加,构造出新的HTNode作为他们的父节点,指针parent,leftchild,rightchild赋相应值。
在把这个新的节点插入最小堆。
按此步骤可以构造构造出一棵哈夫曼树。
通过已经构造出的哈夫曼树,自底向上,由频率节点开始向上寻找parent,直到parent为树的顶点为止。
这样,根据每次向上搜索后,原节点为父节点的左孩子还是右孩子,来记录1或0,这样,每个频率都会有一个01编码与之唯一对应,并且任何编码没有前部分是同其他完整编码一样的。
3、实验步骤
先统计要压缩编码的文件中的字符字母出现的次数,按字符字母和空格出现的概率对其进行哈夫曼编码。
然后读入要编码的文件,编码后存入另一个文件;
接着再调出编码后的文件,并对其进行译码输出,最后存入另一个文件中。
具体步骤:
1.初始化,统计文本文件中各字符的个数作为权值,生成哈夫曼树;
2.根据符号概率的大小按由大到小顺序对符号进行排序;
3.把概率最小的两个符号组成一个节点;
4.重复步骤2.3,直到概率和为1;
5.从根节点开始到相应于每个符号的“树叶”,概率大的标“0”,概率小的标“1”;
6.从根节点开始,对符号进行编码;
7.译码时流程逆向进行,从文件中读出哈夫曼树,并利用哈夫曼树将编码序列解码。
四、实验结果与分析
哈夫曼编码是动态变长编码,临时建立概率统计表和编码树。
概率小的码比较长,概率小的码比较长。
概率大的码短,这样把一篇文件编码后,就会压缩许多。
从树的角度看,哈夫曼编码方式是尽量把短码都利用上。
首先,把一阶节点全都用上,如果码字不够时,然后,再从某个节点伸出若干枝,引出二阶节点作为码字,以此类推,显然所得码长最短,再根据建立的概率统计表合理分布和放置,使其平均码长最短就可以得到最佳码。
实验截图:
五、实验心得
本次实验结合了之前所学的赫夫曼算法,并利用其原理实现赫夫曼编码/译码系统;实验难度较之前的几次实验有所增加,所以花了比较多的时间来编写,测试代码。
期间参考了网上的一些程序,通过结合分析,了解其他人在实现这个算法时的思想,也借鉴了其中的一些东西,同时加入了自己的想法。
最终完成饿了本次的作业。
通过这次实验,我了解了一个算法到一个可以执行的程序之间还有很多工作需要做,深刻体会到实践出真知的到了,看似简单的算法在实现时却话费了这么多时间,但是这个过程中也让我学到了很多。
六、主要代码
Huffman_Tree.h:
#ifndefHuffman_Tree_h
#defineHuffman_Tree_h
#endif
#include
typedefstruct{
unsignedintweight;
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;//存储赫夫曼树的结点类型
typedefchar**HuffmanCode;//用于存储字符集中各个字符相应的赫夫曼编码
voidstrcpy(char*S1,char*S2){//将字符串S2复制到S1
inti=0;
while(S2[i]!
='\0'){
S1[i]=S2[i];
i++;
}
S1[i]='\0';
}
//在HT[1]到HT[t-1]中找出权值最小的两个S1和S2-----------------------------------------------
voidSelect(HuffmanTreeHT,intt,int&s1,int&s2){
inti=1;
s1=s2=0;
HT[0].weight=50000;
while(i<=t){//遍历查找权值最小的结点S1
if(HT[i].parent==0&&HT[i].weight s1=i; i++; } i=1; while(i<=t){//遍历查找除S1外权值最小的结点S2 if(i! =s1&&HT[i].parent==0&&HT[i].weight s2=i; i++; } } //根据各个字符的权值构造赫夫曼树HT,将对应的赫夫曼编码存储在HC中------------------------------------------------ intHuffmanCoding(HuffmanTree&HT,HuffmanCode&HC,int*w,intn){ ints1,s2,m,i,start; unsignedintc,f; HTNode*p; char*cd; if(n<=1)return0; m=2*n-1;//赫夫曼树的总结点树为m HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//申请存储赫夫曼树的空间 for(p=HT+1,i=1;i<=n;++i,++p,++w){//将各个叶子结点的weight赋以相应的权值,parent,lchild,rchild均赋为0 p->weight=*(w+1); p->parent=p->lchild=p->rchild=0; } for(;i<=m;++i,++p){//将各个非叶子结点的weight,parent,lchild,rchild均赋为0 p->weight=p->parent=p->lchild=p->rchild=0; } for(i=n+1;i<=m;++i){//构造赫夫曼树,给各个非叶子结点赋值 Select(HT,i-1,s1,s2); HT[s1].parent=i;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;//编码在数组cd[]中的最前位置 //从叶子到根逆向求编码,初始值;停止条件;一次循环后对上一个节点做循环 for(c=i,f=HT[i].parent;f! =0;c=f,f=HT[f].parent) if(HT[f].lchild==c) cd[--start]='0'; else cd[--start]='1'; HC[i]=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间 strcpy(HC[i],&cd[start]);//将cd[]数组的start位置到n-1位置复制给HC[i] } free(cd);//释放空间 return1; } Test.cpp: #include #include #include"Huffman_Tree.h" #defineYes1//当程序已经调用过初始化赫夫曼树的InitHuff_T()函数,或已从htfTree文件读取过,则将Init_Mode置为Yes,否则为No #defineNo0 voidInitHuff_T(HuffmanTree&HT,HuffmanCode&HC,charch[],int&n){//初始化赫夫曼数,要求用户输入字符和相应权值 inti=1,w[100],temp,j; chara[20];//数字转字符时,用于储存赫夫曼编码 FILE*save; printf("请输入编码字符集的大小: "); scanf("%d",&n);//获取用户输入的字符集个数 while(i<=n){//获取用户输入的字符和相应权值,分别存储在ch[]和w[]数组中 printf("请输入第%d个字符和该字符的权值: ",i); fflush(stdin);//刷新标准输入缓冲区,把输入缓冲区里的东西丢弃 scanf("%c%d",&ch[i],&w[i]); i++; } ch[i]='\0'; //哈夫曼树保存-------------------------------------------------------------------------------------------- HuffmanCoding(HT,HC,w,n);//根据用户的输入,生成赫夫曼数及各个字符相应的赫夫曼编码,分别存在HT树和HC中 if((save=fopen("hfmTree.TXT","w"))==NULL){//打开用于存储赫夫曼树的文件 printf("Openfilefail......\n"); exit(0); } temp=n;//将字符集大小转换成字符形式写入到文件hfmTree.TXT中 j=0; while(temp! =0){//计算数字位数 temp=temp/10; j++; } temp=n;//数字转字符 a[j]='\0'; while(temp! =0){ a[j-1]=(char)(temp%10+48); temp=temp/10; j--; } fputs(a,save); printf("%d\n
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈夫曼 编码 译码 系统
![提示](https://static.bdocx.com/images/bang_tan.gif)