武汉理工大学数据结构与算法综合实验哈夫曼树(1)
huffman树数据结构实验原理

huffman树数据结构实验原理
Huffman树是一种用于数据压缩的数据结构,原理如下:
1. 统计字符频率:首先,对于待压缩的数据,统计每个字符出现的频率。
可以使用哈希表或数组来记录各个字符的频率。
2. 构建最小堆:将每个字符及其频率作为一个节点,构建一个最小堆。
最小堆是一种二叉树,每个节点的值都小于或等于其子节点的值。
3. 构建Huffman树:从最小堆中取出频率最小的两个节点(即出现频率最低的两个字符),将它们合并为一个新的节点,并将新节点的频率设置为两个节点的频率之和。
将新节点插入回最小堆中。
重复这个过程,直到最小堆中只剩下一个节点。
4. 构建Huffman编码表:从Huffman树的根节点出发,根据每个字符所在的路径(左子树为0,右子树为1)来构建Huffman编码表。
Huffman编码表可以使用哈希表或数组来存储,键为字符,值为对应的Huffman编码。
5. 数据压缩:对于待压缩的数据,根据Huffman编码表将每个字符转换为对应的Huffman编码,得到压缩后的数据。
6. 数据解压:对于压缩后的数据,根据Huffman编码表将每个Huffman编码转换为对应的字符,得到解压后的数据。
Huffman树的原理在于通过构建一个最小堆,使用贪心算法来生成一个频率最小的树。
这样生成的树中,频率高的字符在树的顶部,频率低的字符在树的底部,从而实现数据压缩。
哈夫曼树_实验报告

一、实验目的1. 理解哈夫曼树的概念及其在数据结构中的应用。
2. 掌握哈夫曼树的构建方法。
3. 学习哈夫曼编码的原理及其在数据压缩中的应用。
4. 提高编程能力,实现哈夫曼树和哈夫曼编码的相关功能。
二、实验原理哈夫曼树(Huffman Tree)是一种带权路径长度最短的二叉树,又称为最优二叉树。
其构建方法如下:1. 将所有待编码的字符按照其出现的频率排序,频率低的排在前面。
2. 选择两个频率最低的字符,构造一棵新的二叉树,这两个字符分别作为左右子节点。
3. 计算新二叉树的频率,将新二叉树插入到排序后的字符列表中。
4. 重复步骤2和3,直到只剩下一个节点,这个节点即为哈夫曼树的根节点。
哈夫曼编码是一种基于哈夫曼树的编码方法,其原理如下:1. 从哈夫曼树的根节点开始,向左子树走表示0,向右子树走表示1。
2. 每个叶子节点对应一个字符,记录从根节点到叶子节点的路径,即为该字符的哈夫曼编码。
三、实验内容1. 实现哈夫曼树的构建。
2. 实现哈夫曼编码和译码功能。
3. 测试实验结果。
四、实验步骤1. 创建一个字符数组,包含待编码的字符。
2. 创建一个数组,用于存储每个字符的频率。
3. 对字符和频率进行排序。
4. 构建哈夫曼树,根据排序后的字符和频率,按照哈夫曼树的构建方法,将字符和频率插入到哈夫曼树中。
5. 实现哈夫曼编码功能,遍历哈夫曼树,记录从根节点到叶子节点的路径,即为每个字符的哈夫曼编码。
6. 实现哈夫曼译码功能,根据哈夫曼编码,从根节点开始,按照0和1的路径,找到对应的叶子节点,即为解码后的字符。
7. 测试实验结果,验证哈夫曼编码和译码的正确性。
五、实验结果与分析1. 构建哈夫曼树根据实验数据,构建的哈夫曼树如下:```A/ \B C/ \ / \D E F G```其中,A、B、C、D、E、F、G分别代表待编码的字符。
2. 哈夫曼编码根据哈夫曼树,得到以下字符的哈夫曼编码:- A: 00- B: 01- C: 10- D: 11- E: 100- F: 101- G: 1103. 哈夫曼译码根据哈夫曼编码,对以下编码进行译码:- 00101110111译码结果为:BACGACG4. 实验结果分析通过实验,验证了哈夫曼树和哈夫曼编码的正确性。
数据结构 哈夫曼编码实验报告

数据结构哈夫曼编码实验报告数据结构哈夫曼编码实验报告1. 实验目的本实验旨在通过实践理解哈夫曼编码的原理和实现方法,加深对数据结构中树的理解,并掌握使用Python编写哈夫曼编码的能力。
2. 实验原理哈夫曼编码是一种用于无损数据压缩的算法,通过根据字符出现的频率构建一棵哈夫曼树,并根据哈夫曼树对应的编码。
根据哈夫曼树的特性,频率较低的字符具有较长的编码,而频率较高的字符具有较短的编码,从而实现了对数据的有效压缩。
实现哈夫曼编码的主要步骤如下:1. 统计输入文本中每个字符的频率。
2. 根据字符频率构建哈夫曼树,其中树的叶子节点代表字符,内部节点代表字符频率的累加。
3. 遍历哈夫曼树,根据左右子树的关系对应的哈夫曼编码。
4. 使用的哈夫曼编码对输入文本进行编码。
5. 将编码后的二进制数据保存到文件,同时保存用于解码的哈夫曼树结构。
6. 对编码后的文件进行解码,还原原始文本。
3. 实验过程3.1 统计字符频率首先,我们需要统计输入文本中每个字符出现的频率。
可以使用Python中的字典数据结构来记录字符频率。
遍历输入文本的每个字符,将字符添加到字典中,并递增相应字符频率的计数。
```pythondef count_frequency(text):frequency = {}for char in text:if char in frequency:frequency[char] += 1else:frequency[char] = 1return frequency```3.2 构建哈夫曼树根据字符频率构建哈夫曼树是哈夫曼编码的核心步骤。
我们可以使用最小堆(优先队列)来高效地构建哈夫曼树。
首先,将每个字符频率作为节点存储到最小堆中。
然后,从最小堆中取出频率最小的两个节点,将它们作为子树构建成一个新的节点,新节点的频率等于两个子节点频率的和。
将新节点重新插入最小堆,并重复该过程,直到最小堆中只剩下一个节点,即哈夫曼树的根节点。
数据结构哈夫曼树实验报告

数据结构哈夫曼树实验报告一、实验内容本次实验的主要内容是哈夫曼树的创建和编码解码。
二、实验目的1. 理解并掌握哈夫曼树的创建过程;2. 理解并掌握哈夫曼编码的原理及其实现方法;3. 掌握哈夫曼树的基本操作,如求哈夫曼编码和哈夫曼解码等;4. 学习如何组织程序结构,运用C++语言实现哈夫曼编码和解码。
三、实验原理哈夫曼树的创建:哈夫曼树的创建过程就是一个不断合并权值最小的两个叶节点的过程。
具体步骤如下:1. 将所有节点加入一个无序的优先队列里;2. 不断地选出两个权值最小的节点,并将它们合并成为一个节点,其权值为这两个节点的权值之和;3. 将新的节点插入到队列中,并继续执行步骤2,直到队列中只剩下一棵树,这就是哈夫曼树。
哈夫曼编码:哈夫曼编码是一种无损压缩编码方式,它根据字符出现的频率来构建编码表,并通过编码表将字符转换成二进制位的字符串。
具体实现方法如下:1. 统计每个字符在文本中出现的频率,用一个数组记录下来;2. 根据字符出现的频率创建哈夫曼树;3. 从根节点开始遍历哈夫曼树,给左分支打上0的标记,给右分支打上1的标记。
遍历每个叶节点,将对应的字符及其对应的编码存储在一个映射表中;4. 遍历文本中的每个字符,查找其对应的编码表,并将编码字符串拼接起来,形成一个完整的编码字符串。
哈夫曼解码就是将编码字符串还原为原始文本的过程。
具体实现方法如下:1. 从根节点开始遍历哈夫曼树,按照编码字符串的位数依次访问左右分支。
如果遇到叶节点,就将对应的字符记录下来,并重新回到根节点继续遍历;2. 重复步骤1,直到编码字符串中的所有位数都被遍历完毕。
四、实验步骤1. 定义编码和解码的结构体以及相关变量;3. 遍历哈夫曼树,得到每个字符的哈夫曼编码,并将编码保存到映射表中;4. 将文本中的每个字符用其对应的哈夫曼编码替换掉,并将编码字符串写入到文件中;5. 使用哈夫曼编码重新构造文本,并将结果输出到文件中。
五、实验总结通过本次实验,我掌握了哈夫曼树的创建和哈夫曼编码的实现方法,也学会了如何用C++语言来组织程序结构,实现哈夫曼编码和解码。
武汉理工大学数据结构与算法综合实验哈夫曼树

..
v
.. .
..
.
typedef char * pBuffer ; //其大小视原文件压缩后的大小
2.核心算法设计
(1)生成 Huffman 树和 Huffman 编码的算法 void Select(HTNode huffTree[],int m) {
int min,min2,i; min=min2=1000; for(i=0;i<m;i++)
b=b<<1; if(pBinStr[i]=='1') {
b=b|0x01; } } return b; } bool InitHead(const char *pFilename,HEAD &sHead) { char ch;
..
v
.. . .. .
..
.
.. .
//初始化文件 strcpy(sHead.type,"HUF"); sHead.length=0; for(int i=0;i<256;i++) {
..
v
.. .
..
.
.. .
二叉树的存储结构。使用结构体存储节点,使用数组存储树的节点,使用静态二叉链表方 式存储二叉树。
Huffman编码存储结构 struct HTNode
{ int weight;//权值 int parent; int lchild; int rchild; char zifu; string bianma;
..
.
.. .
学生学号
Xxx
实验课成绩
学生实验报告书
实验课程名称 开课学院
指导教师姓名 学生姓名
数据结构哈夫曼编码实验报告

数据结构哈夫曼编码实验报告【正文】1.实验目的本实验旨在研究哈夫曼编码的原理和实现方法,通过实验验证哈夫曼编码在数据压缩中的有效性,并分析其应用场景和优缺点。
2.实验原理2.1 哈夫曼编码哈夫曼编码是一种无损数据压缩算法,通过根据字符出现的频率构建一颗哈夫曼树,将频率较高的字符用较短的编码表示,频率较低的字符用较长的编码表示。
哈夫曼编码的编码表是唯一的,且能够实现前缀编码,即一个编码不是另一个编码的前缀。
2.2 构建哈夫曼树构建哈夫曼树的过程如下:1) 将每个字符及其频率作为一个节点,构建一个节点集合。
2) 每次从节点集合中选择出现频率最低的两个节点,构建一个新节点,并将这两个节点从集合中删除。
3) 将新节点加入节点集合。
4) 重复以上步骤,直到节点集合中只有一个节点,这个节点就是哈夫曼树的根节点。
2.3 编码过程根据哈夫曼树,对每个字符进行编码:1) 从根节点开始,根据左子树为0,右子树为1的规则,将编码依次加入编码表。
2) 对于每个字符,根据编码表获取其编码。
3) 将编码存储起来,得到最终的编码序列。
3.实验步骤3.1 数据读取与统计从输入文件中读取字符序列,并统计各个字符的频率。
3.2 构建哈夫曼树根据字符频率构建哈夫曼树。
3.3 构建编码表根据哈夫曼树,构建每个字符的编码表。
3.4 进行编码根据编码表,对输入的字符序列进行编码。
3.5 进行解码根据哈夫曼树,对编码后的序列进行解码。
4.实验结果与分析4.1 压缩率分析计算原始数据和压缩后数据的比值,分析压缩率。
4.2 编码效率分析测试编码过程所需时间,分析编码效率。
4.3 解码效率分析测试解码过程所需时间,分析解码效率。
4.4 应用场景分析分析哈夫曼编码在实际应用中的优势和适用场景。
5.结论通过本次实验,我们深入了解了哈夫曼编码的原理和实现方法,实践了哈夫曼编码的过程,并对其在数据压缩中的有效性进行了验证。
实验结果表明,哈夫曼编码能够实现较高的压缩率和较高的编解码效率。
数据结构哈夫曼树

数据结构哈夫曼树哈夫曼树(Huffman tree)是一种用于编码的树形数据结构,由美国计算机科学家大卫·哈夫曼(David A. Huffman)于1952年提出。
它是一种利用最高频率字符具有最短编码长度的特性来进行数据压缩的算法。
在介绍哈夫曼树之前,我们先来了解一下哈夫曼编码(Huffman coding)。
哈夫曼编码是一种变长前缀编码,即每个字符的编码长度不固定,不会出现编码前缀相同的情况,具有唯一可解码性。
它是为了满足字符编码长度尽可能短且无编码前缀相同的要求而产生的。
构建哈夫曼树的过程可以分为以下几步:1.统计字符频率:首先对于需要压缩的文件,统计每个字符出现的频率。
频率可以理解为该字符出现的次数。
统计之后,可以得到每个字符与其对应的频率。
2.构建节点:将每个字符以及其频率作为叶子节点构建成一个森林(每个节点都是一个独立的树)。
3.合并节点:从森林中选取频率最小的两个节点合并为一个新的节点,频率为其子节点频率之和。
将新的节点继续加入森林中,重复此过程,直到森林中只剩下一个节点为止。
4.构建哈夫曼树:最后剩下的那个节点就是哈夫曼树的根节点。
从构建的过程可以看出,频率较高的字符会位于树的较低层,而频率较低的字符会位于树的较高层。
5.生成编码:根据哈夫曼树的特点,路径的左边为0,右边为1,从根节点开始,走到每个叶子节点的路径就是该叶子节点的哈夫曼编码。
通过以上步骤,我们就构建了一颗哈夫曼树,并生成了对应的哈夫曼编码。
利用哈夫曼编码,可以将原始数据进行压缩,使其占用的存储空间减小。
举个例子来说明哈夫曼树的构建过程和编码生成过程:假设有一个包含5个不同字符的文件,每个字符及其频率如下:A:5B:9C:12D:13E:16首先按照步骤1统计字符频率,得到每个字符及其频率。
然后按照步骤2构建叶子节点,每个字符和其频率构成一个叶子节点。
接着按照步骤3合并节点,选取频率最小的两个节点合并为一个新的节点,直到森林中只剩下一个节点。
哈夫曼树实验报告

哈夫曼树实验报告一、实验目的1.理解哈夫曼树的概念和实现原理;2.掌握使用哈夫曼树进行编码和解码的方法;3.熟悉哈夫曼树在数据压缩中的应用。
二、实验原理哈夫曼树是一种用于数据压缩的树形结构,通过将出现频率较高的数据项用较短的编码表示,从而达到压缩数据的目的。
哈夫曼树的构建过程如下:1.统计字符出现的频率,并按照频率从小到大排序;2.将频率最低的两个字符合并为一个节点,节点的频率为两个字符的频率之和;3.将新节点插入频率表,并将频率表重新排序;4.重复步骤2和3,直到频率表中只剩下一个节点,该节点即为哈夫曼树的根节点。
三、实验步骤1.统计输入的字符序列中每个字符出现的频率;2.根据频率构建哈夫曼树;3.根据哈夫曼树生成字符的编码表;4.将输入的字符序列编码为哈夫曼编码;5.根据哈夫曼树和编码表,解码得到原始字符序列。
四、实验结果以字符序列"abacabad"为例进行实验:1.统计字符频率的结果为:a-4次,b-2次,c-1次,d-1次;```a-4/\b-2c-1/\d-1空节点```3.根据哈夫曼树生成的编码表为:a-0,b-10,c-110,d-111;5. 根据哈夫曼树和编码表进行解码得到原始字符序列:"abacabad"。
五、实验总结通过本次实验,我深入了解了哈夫曼树的原理和实现方法,掌握了使用哈夫曼树进行字符编码和解码的过程。
哈夫曼树在数据压缩中的应用非常广泛,能够有效地减小数据的存储空间,提高数据传输效率。
在实际应用中,我们可以根据不同字符出现的频率构建不同的哈夫曼树,从而实现更高效的数据压缩和解压缩算法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学生学号Xxx实验课成绩学生实验报告书实验课程名称数据结构与算法综合实验开课学院计算机科学与技术学院指导教师姓名xxx学生姓名xxx学生专业班级xxxx2015--2016学年第2学期实验课程名称:数据结构与算法综合实验实验项目名称二叉树与赫夫曼图片压缩报告成绩实验者xx专业班级xxx组别同组者完成日期2016年5月 2日第一部分:实验分析与设计(可加页)一、实验目的和要求1.目的掌握树的存储结构掌握二叉树的三种遍历方法掌握 Huffman树、Huffman编码等知识和应用使用 C++、文件操作和 Huffman算法实现“图片压缩程序”专题编程。
2.要求针对一幅 BMP 格式的图片文件,统计 256 种不同字节的重复次数,以每种字节重复次数作为权值,构造一颗有 256 个叶子节点的哈夫曼二叉树。
利用上述哈夫曼树产生的哈夫曼编码对图片文件进行压缩。
压缩后的文件与原图片文件同名,加上后缀.huf (保留原后缀),如 pic.bmp 压缩后 pic.bmp.huf二、分析与设计依据上述的实验目的与要求,可导出实现的二叉树与赫夫曼图片压缩软件的流程为:① 读取图片文件、统计权值②生成 Huffman树③生成 Huffman编码④ 压缩图片文件⑤ 保存压缩的文件1.数据结构的设计记录统计 256种不同字节的重复次数使用整型数组。
int weight[256] = { 0 };二叉树的存储结构。
使用结构体存储节点,使用数组存储树的节点,使用静态二叉链表方式存储二叉树。
Huffman编码存储结构struct HTNode{int weight;//权值1int lchild;int rchild;char zifu;string bianma;};压缩文件的算法的数据结构为正确解压文件,除了要保存原文件长度外,还要保存原文件中 256种字节重复的次数,即权值。
定义一个文件头,保存相关的信息:struct HEAD{char type[4];int length;int weight[256];};压缩文件时,定义一个内存缓冲区:typedef char *pBuffer;//其大小视原文件压缩后的大小2.核心算法设计(1) 生成 Huffman 树和 Huffman 编码的算法void Select(HTNode huffTree[],int m){int min,min2,i;min=min2=1000;for(i=0;i<m;i++)if(huffTree[i].parent==-1)if(min>huffTree[i].weight ){min2=min;min=huffTree[i].weight ;x2=x1;x1=i;}else if(min2>huffTree[i].weight ){min2=huffTree[i].weight ;x2=i;}}void creatHuffman(int huff[]){int i;int s=256;for(i=0;i<2*s-1;i++){HuffmanTree[i].parent =-1;HuffmanTree[i].lchild =-1;HuffmanTree[i].rchild =-1;}for(int i1=0;i1<s;i1++)HuffmanTree[i1].weight=huff[i1];for(int k=s;k<2*s-1;k++){Select(HuffmanTree,k);HuffmanTree[x1].parent =k;HuffmanTree[x2].parent =k;HuffmanTree[k].weight =HuffmanTree[x1].weight +HuffmanTree[x2].weight ;HuffmanTree[k].lchild =x1;HuffmanTree[k].rchild =x2;}}void HuffmanCoding(HTNode huffTree[],int n){int i,j=0;for(i=2*(n-1);i>n-1;i--){huffTree[huffTree[i].lchild ].bianma ="0";huffTree[huffTree[i].rchild ].bianma ="1";}for(i=0,j=0;j<n;j++){while(huffTree[i].parent !=-1){huffTree[j].bianma =huffTree[huffTree[i].parent].bianma+huffTree[j].bianma ;i=huffTree[i].parent ;}i=j+1;}}(2)压缩编码算法struct HEAD{char type[4];int length;int weight[256];};char Str2byte(const char * pBinStr){char b=0x00;for(int i=0;i<8;i++){b=b<<1;if(pBinStr[i]=='1'){b=b|0x01;}}return b;}bool InitHead(const char *pFilename,HEAD &sHead){char ch;//初始化文件strcpy(sHead.type,"HUF");sHead.length=0;for(int i=0;i<256;i++){sHead.weight[i]=0;}ifstream in;in.open(pFilename,ios::binary);while(in.get(ch)){ sHead.weight[(unsigned char)ch]++;sHead.length++;} cout<<sHead.length<<" 字节 "<<endl;return true;}int Encode(const char *pFilename,char * &pBuffer,const int nSize){pBuffer=(char *)malloc(nSize * sizeof(char)+10);if(!pBuffer){cout<<" 开辟缓冲区失败 "<<endl;}char cd[256]={0};int pos=0;int ch;FILE *in=fopen(pFilename,"rb");while((ch=fgetc(in))!=EOF){strcat(cd,HuffmanTree[ch].bianma.c_str());while(strlen(cd)>=8){//cout<<cd<<" "<<Str2byte(cd)<<" ";pBuffer[pos++]=Str2byte(cd);//cout<<pBuffer[pos-1]<<endl;for(int i=0;i<256-8;i++){cd[i]=cd[i+8];}}}if(strlen(cd)>0){pBuffer[pos++]=Str2byte(cd);}return 1;}int WriteFile(const char * pFilename ,const HEAD sHead, char * pBuffer,const int nSize) {//生成文件名char filename[256]={0};strcpy(filename,pFilename);int i;for( i=strlen(filename);filename[i]!='.';i--);filename[i]='\0';strcat(filename,".huf");//以二进制流的形式打开文件FILE *out =fopen(filename ,"wb");//写文件头fwrite( & sHead,sizeof(HEAD),1,out);//写压缩后的编码fwrite(pBuffer,sizeof(char),nSize,out);//关闭文件释放文件指针fclose(out);out=NULL;cout<<" 生成压缩文件 "<<filename<<endl;int len=sizeof(HEAD)+strlen(pFilename)+1+nSize;return len;}int compress(const char *pFilename,int weight[256],const HEAD sHead){//计算缓冲区的大小int nSize=0; for(inti=0;i<256;i++){nSize+=weight[i]*HuffmanTree[i].bianma.length();}nSize=(nSize%8)?nSize/8+1:nSize/8;//cout<<"nSize"<<nSize<<endl;char *pBuffer=NULL;Encode(pFilename,pBuffer,nSize);//if(pBuffer==NULL)// cout<<" wrong"<<endl;if(!pBuffer){return 0;}int result=WriteFile(pFilename,sHead,pBuffer,nSize);return result;}3.测试用例设计使用一个文本文件作为压缩的例,观察其压缩比;通过屏幕截图形成一个 BMP图片文件,观察其压缩比;在互联网上搜索下载任意格式的图片文件,观察其压缩比。
三、主要仪器设备及耗材1. 安装了 Windows 10 或其它版本的 Windows操作系统的 PC机 1 台2.PC 机系统上安装了Microsoft Visual Studio 2010开发环境第二部分:实验过程和结果(可加页)一、实现说明在 Microsoft Visual Studio 2010集成开发环境中新建一个Win32 控制台应用程序工程HfmCompressConsole。