哈夫曼编码译码系统
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《数据结构》课程设计——赫夫曼编码/译码器设计
指导教师:孙树森、周维达
班级:09数媒(2)班
学号:E********
姓名:***
数据结构课程设计报告书
一、实验目的
1、提高分析问题、解决问题的能力,进一步巩固数据结构各种原理与方法。
2、熟悉掌握一门计算机语言,可以进行数据算法的设计。
二、实验原理
1、哈夫曼树的定义:
假设有n 个权值,试构造一颗有n 个叶子节点的二叉树,每个叶子带权值为wi,其中树带权路径最小的二叉树成为哈夫曼树或者最优二叉树;
2、哈夫曼树的构造:
weight 为输入的频率数组,把其中的值赋给依次建立的HT Node 对象中的data 属性,即每一个HT Node 对应一个输入的频率。然后根据data 属性按从小到大顺序排序,每次从data 取出两个最小和此次小的HT Node,将他们的data 相加,构造出新的HTNode 作为他们的父节点,指针parent,leftchild,rightchild 赋相应值。在把这个新的节点插入最小堆。按此步骤可以构造构造出一棵哈夫曼树。通过已经构造出的哈夫曼树,自底向上,由频率节点开始向上寻找parent,直到parent 为树的顶点为止。这样,根据每次向上搜索后,原节点为父节点的左孩子还是右孩子,来记录1 或0,这样,每个频率都会有一个01 编码与之唯一对应,并且任何编码没有前部分是同其他完整编码一样的。
三、实验步骤
先统计要压缩编码的文件中的字符字母出现的次数,按字符字母和空格出现的概率对其进行哈夫曼编码。
然后读入要编码的文件,编码后存入另一个文件;
接着再调出编码后的文件,并对其进行译码输出,最后存入另一个文件中。
具体步骤:
1.初始化,统计文本文件中各字符的个数作为权值,生成哈夫曼树;
2.根据符号概率的大小按由大到小顺序对符号进行排序;
3.把概率最小的两个符号组成一个节点;
4.重复步骤2. 3 ,直到概率和为1;
5.从根节点开始到相应于每个符号的“树叶”,概率大的标“0”,概率小的标“1”;
6.从根节点开始,对符号进行编码;
7.译码时流程逆向进行,从文件中读出哈夫曼树,并利用哈夫曼树将编码序列解码。
四、实验结果与分析
哈夫曼编码是动态变长编码,临时建立概率统计表和编码树。概率小的码比较长,概率小的码比较长。概率大的码短,这样把一篇文件编码后,就会压缩许多。
从树的角度看,哈夫曼编码方式是尽量把短码都利用上。首先,把一阶节点全都用上,如果码字不够时,然后,再从某个节点伸出若干枝,引出二阶节点作为码字,以此类推,显
然所得码长最短,再根据建立的概率统计表合理分布和放置,使其平均码长最短就可以得到最佳码。
实验截图:
五、实验心得
本次实验结合了之前所学的赫夫曼算法,并利用其原理实现赫夫曼编码/译码系统;实验难度较之前的几次实验有所增加,所以花了比较多的时间来编写,测试代码。期间参考了网上的一些程序,通过结合分析,了解其他人在实现这个算法时的思想,也借鉴了其中的一些东西,同时加入了自己的想法。最终完成饿了本次的作业。通过这次实验,我了解了一个算法到一个可以执行的程序之间还有很多工作需要做,深刻体会到实践出真知的到了,看似简单的算法在实现时却话费了这么多时间,但是这个过程中也让我学到了很多。
六、主要代码
Huffman_Tree.h:
#ifndef Huffman_Tree_h
#define Huffman_Tree_h
#endif
#include
typedef struct {
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode, * HuffmanTree; //存储赫夫曼树的结点类型
typedef char * * HuffmanCode; //用于存储字符集中各个字符相应的赫夫曼编码
void strcpy(char *S1,char *S2){ //将字符串S2复制到S1
int i = 0;
while( S2[i] != '\0' ){
S1[i] = S2[i];
i++;
}
S1[i] = '\0';
}
//在HT[1]到HT[t-1]中找出权值最小的两个S1和S2----------------------------------------------- void Select(HuffmanTree HT,int t,int &s1,int &s2){
int i = 1;
s1 = s2 = 0;
HT[0].weight = 50000;
while( i <= t ){ //遍历查找权值最小的结点S1
if( HT[i].parent == 0 && HT[i].weight < HT[s1].weight )
s1 = i;
i++;
}
i = 1;
while( i <= t ){ //遍历查找除S1外权值最小的结点S2
if( i != s1 && HT[i].parent == 0 && HT[i].weight < HT[s2].weight )
s2 = i;
i++;
}
}
//根据各个字符的权值构造赫夫曼树HT,将对应的赫夫曼编码存储在HC中
------------------------------------------------
int HuffmanCoding( 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;