PAGE
实 验 报 告
课程名称: 数据结构
实验名称: 赫夫曼编码及应用
院 (系): 计算机与通信工程学院
专业班级: 计算机科学与技术
姓 名:
学 号:
指导教师:
2020 年 5 月 12 日
一、实验目的
掌握赫夫曼树和赫夫曼编码的基本思想和算法的程序实现。
二、实验内容及要求
任务描述a.提取原始文件中的数据(包括中文、英文或其他字符),根据数据出现的频率为权重,b.构建Huffman编码表;
c.根据Huffman编码表对原始文件进行加密,得到加密文件并保存到硬盘上;
d.将加密文件进行解密,得到解码文件并保存点硬盘上;
e.比对原始文件和解码文件的一致性,得出是否一致的结论。
主要数据类型与变量
a.对Huffman树采用双亲孩子表示法,便于在加密与解密时的操作。typedef struct Huffman* HuffmanTree;
struct Huffman
{
unsigned int weight; //权值
unsigned int p, l, r;//双亲,左右孩子
};
b.对文本中出现的所有字符用链表进行存储。
typedef struct statistics* List;
struct statistics {
char str; //存储此字符
int Frequency; //出现的频率(次数)
string FinalNum; //Huffman编码
struct statistics* Next;
};
算法或程序模块 对读取到的文本进行逐字符遍历,统计每个字符出现的次数,并记录在创建的链表中。借助Huffman树结构,生成结构数组,先存储在文本中出现的所有字符以及它们出现的频率(即权值),当作树的叶子节点。再根据叶子节点生成它们的双亲节点,同样存入Huffman树中。 在完成对Huffman树的创建与存储之后,根据树节点的双亲节点域以及孩子节点域,生成每个字符的Huffman编码,并存入该字符所在链表节点的FinalNum域。解码同理。
List CreateList();//创建链表时,头节点的域用来存储当前有效节点数(即Huffman树叶子节点数)
void Judge(List L, char s);//判断在链表中是否已经存在该字符,存在则对该字符所在的链表节点中的Frequency(出现的次数)域加1,否则则创建新节点保存该字符;
void Find(int* x, int* y, HuffmanTree HF);//用来在Huffman树中寻找权值最小的叶子节点,生成新的节点同样保存在树结构中
void HUFFMANTREE(HuffmanTree HF, List L);//构建Huffman树,将链表L中保存的是文本中出现的字符以及它们的出现次数(权值)保存在HF结构数组中,同时在寻找最小权值后,记录它们的双亲位置和左右孩子位置。
void Encryption(HuffmanTree HF, List L);//加密文本,将所得的每个字符的Huffman编码存入该字符所在链表L中节点的FinalNum域。方法是从每个叶子节点出发,向上寻找双亲,同时通过判断是左孩子或右孩子,记录编码“0”或“1”保存在string字符串。最后将字符串逆置即是该字符的Huffman编码。
三、测试
方案采用平台:Visual studio2015,c++语言在磁盘文本文件中输入一段英文句子,程序通过对文件的读取进行编码、加密与解密。
结果
输出结果中,首先输出从硬盘中读取的原始文本文件,再输出文本各字符出现的次数,并输出对每个字符的Huffman编码值,最后输出按照所得的Huffman编码值加密的文本,按照所得Huffman编码值解密的文本。
总结与讨论
在这次的实验中,参考了在实验指导书中提供的Huffman树的存储结构,同时自己加入了链表存储结构,并且独自完成了程序代码所有的步骤。
在选择存储结构时,选择了链式存储结