哈夫曼树实验报告
- 格式:docx
- 大小:67.45 KB
- 文档页数:7
哈夫曼树的实验报告1一、需求分析1、本演示程序实现Haffman编/译码器的作用,目的是为信息收发站提供一个编/译系统,从而使信息收发站利用Haffman编码进行通讯,力求达到提高信道利用率,缩短时间,降低成本等目标。
系统要实现的两个基本功能就是:①对需要传送的数据预先编码;②对从接收端接收的数据进行译码;2、本演示程序需要在终端上读入n个字符(字符型)及其权值(整形),用于建立Huffman树,存储在文件hfmanTree.txt中;如果用户觉得不够清晰还可以打印以凹入表形式显示的Huffman树;3、本演示程序根据建好的Huffman树,对文件的文本进行编码,结果存入文件CodeFile中;然后利用建好的Huffman树将文件CodeFile中的代码进行译码,结果存入文件TextFile中;最后在屏幕上显示代码(每行50个),同时显示对CodeFile中代码翻译后的结果;4、本演示程序将综合使用C++和C语言;5、测试数据:(1)教材例6-2中数据:8个字符,概率分别是0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,可将其的权值看为5,29,7,8,14,23,3,11(2)用下表给出的字符集和频度的实际统计数据建立Haffman树,并实现以下报文的编码和一、概要设计1、设定哈夫曼树的抽象数据类型定义ADT Huffmantree{数据对象:D={a i| a i∈Charset,i=1,2,3,……n,n≥0}数据关系:R1={< a i-1, a i >| a i-1, a i∈D, i=2,3,……n}基本操作:Initialization(&HT,&HC,w,n,ch)操作结果:根据n个字符及其它们的权值w[i],建立Huffman树HT,用字符数组ch[i]作为中间存储变量,最后字符编码存到HC中;Encodeing(n)操作结果:根据建好的Huffman树,对文件进行编码,编码结果存入到文件CodeFile 中Decodeing(HT,n)操作结果:根据已经编译好的包含n个字符的Huffman树HT,将文件的代码进行翻译,结果存入文件T extFile中} ADT Huffmantree1)主程序模块void main(){输入信息,初始化;选择需要的操作;生成Huffman树;执行对应的模块程序;输出结果;}2)编码模块——根据建成的Huffman树对文件进行编码;3)译码模块——根据相关的Huffman树对编码进行翻译;各模块的调用关系如图所示二、详细设计1、树类型定义typedef struct {unsigned int weight; //权值char ch1; //储存输入的字符unsigned int parent,lchild,rchild;}HTNode,*HuffmanTree;2、编码类型定义typedef char **HuffmanCode;哈夫曼编译器的基本操作设置如下Initialization(HuffmanTree &HT,HuffmanCode &HC,int *w,int &n,char *ch) //根据输入的n个字符及其它们的权值w[i],建立Huffman树HT,用字符数组ch[i]作为中间存储变量存储编码,最后转存到HC中;Encodeing(int n)//根据建好的包含n个字符的Huffman树,对文件进行编码,编码结果存入到文件CodeFile中Decodeing(HuffmanTree HT,int n)//根据已经编译好的包含n个字符的Huffman树HT,对文件的代码进行翻译,结果存入文件TextFile中基本操作操作的算法主函数及其他函数的算法void select(HuffmanTree HT,int n,int &s1,int &s2){ //依次比较,从哈夫曼树的中parent为0的节点中选择出两个权值最小的if(!HT[i].parent&&!HT[S1]&&!HT[S2]){if(HT[i].weight<ht[s1].weight){< p="">s2=s1; s1=i;}else if(HT[i].weight<ht[s2].weight&&i!=s1)< p=""> s2=i;}3、函数的调用关系图三、调试分析Encodeing Decoding Print PrintTreeInitialization1、本次实习作业最大的难点就是文件的读和写,这需要充分考虑到文件里面的格式,例如空格,换行等等,由于不熟悉C++语言和C语言的文件的输入和输出,给编程带来了很大的麻烦;2、原本计划将文本中的换行格式也进行编码,也由于设计函数比较复杂,而最终放弃;3、一开始考虑打印哈夫曼树的凹入表时是顺向思维,希望通过指针的顺序变迁来实现打印,但问题是从根结点到叶子结点的指针不是顺序存储的,所以未能成功,后来查找相关资料,最终利用递归的方法解决问题;4、程序中的数组均采用了动态分配的方法定义,力求达到减少空间的浪费;5、时间的复杂度主要是由查树这个步骤决定,因为无论是编码还是译码都需要对Huffman树进行查找和核对,但考虑到英文字母和空格也就是27个字符,影响不是很大;6、程序无论在屏幕显示还有文件存储方面都达到了不错的效果;7、程序不足的地方就是在文件文本格式方面处理得还是不够,或许可以通过模仿WORD的实现来改善。
一、实验目的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、课题设计目的:在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。
哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,时常应用于数据压缩。
哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。
这张编码表的特殊之处在于,它是根据每一个源字符浮现的估算概率而建立起来的。
课题设计目的与设计意义2、课题设计意义:哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。
树中从根到每一个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或者“1”的序列作为和各个叶子对应的字符的编码,这就是哈夫曼编码。
哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。
指导教师:年月日第一章需求分析 (1)第二章设计要求 (1)第三章概要设计 (2)(1)其主要流程图如图 1-1 所示。
(3)(2)设计包含的几个方面 (4)第四章详细设计 (4)(1)①哈夫曼树的存储结构描述为: (4)(2)哈弗曼编码 (5)(3)哈弗曼译码 (7)(4)主函数 (8)(5)显示部份源程序: (8)第五章调试结果 (10)第六章心得体味 (12)第七章参考文献 (12)附录: (12)在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。
哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,时常应用于数据压缩。
哈弗曼编码使用一张特殊的编码表将源字符 (例如某文件中的一个符号) 进行编码。
哈夫曼树编码实验报告哈夫曼树编码实验报告引言:哈夫曼树编码是一种常用的数据压缩算法,通过对数据进行编码和解码,可以有效地减小数据的存储空间。
本次实验旨在探究哈夫曼树编码的原理和应用,并通过实际案例验证其有效性。
一、哈夫曼树编码原理哈夫曼树编码是一种变长编码方式,根据字符出现的频率来确定不同字符的编码长度。
频率较高的字符编码较短,频率较低的字符编码较长,以达到最佳的数据压缩效果。
1.1 字符频率统计首先,需要对待编码的数据进行字符频率统计。
通过扫描数据,记录每个字符出现的次数,得到字符频率。
1.2 构建哈夫曼树根据字符频率构建哈夫曼树,频率较低的字符作为叶子节点,频率较高的字符作为父节点。
构建哈夫曼树的过程中,需要使用最小堆来维护节点的顺序。
1.3 生成编码表通过遍历哈夫曼树,从根节点到每个叶子节点的路径上的左右分支分别赋予0和1,生成对应的编码表。
1.4 数据编码根据生成的编码表,将待编码的数据进行替换,将每个字符替换为对应的编码。
编码后的数据长度通常会减小,实现了数据的压缩。
1.5 数据解码利用生成的编码表,将编码后的数据进行解码,恢复原始数据。
二、实验过程与结果为了验证哈夫曼树编码的有效性,我们选择了一段文本作为实验数据,并进行了以下步骤:2.1 字符频率统计通过扫描文本,统计每个字符出现的频率。
我们得到了一个字符频率表,其中包含了文本中出现的字符及其对应的频率。
2.2 构建哈夫曼树根据字符频率表,我们使用最小堆构建了哈夫曼树。
频率较低的字符作为叶子节点,频率较高的字符作为父节点。
最终得到了一棵哈夫曼树。
2.3 生成编码表通过遍历哈夫曼树,我们生成了对应的编码表。
编码表中包含了每个字符的编码,用0和1表示。
2.4 数据编码将待编码的文本数据进行替换,将每个字符替换为对应的编码。
编码后的数据长度明显减小,实现了数据的压缩。
2.5 数据解码利用生成的编码表,将编码后的数据进行解码,恢复原始文本数据。
数据结构哈夫曼编码实验报告【正文】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.结论通过本次实验,我们深入了解了哈夫曼编码的原理和实现方法,实践了哈夫曼编码的过程,并对其在数据压缩中的有效性进行了验证。
实验结果表明,哈夫曼编码能够实现较高的压缩率和较高的编解码效率。
哈夫曼树实验报告哈夫曼树实验报告引言:哈夫曼树是一种经典的数据结构,广泛应用于数据压缩、编码和解码等领域。
本次实验旨在通过构建哈夫曼树,探索其原理和应用。
一、哈夫曼树的定义和构建方法哈夫曼树是一种特殊的二叉树,其叶子节点对应于待编码的字符,而非叶子节点则是字符的编码。
构建哈夫曼树的方法是通过贪心算法,即每次选择权值最小的两个节点合并,直到构建出完整的哈夫曼树。
二、哈夫曼编码的原理和实现哈夫曼编码是一种可变长度编码,即不同字符的编码长度不同。
其原理是通过构建哈夫曼树来确定字符的编码,使得频率较高的字符编码较短,频率较低的字符编码较长。
这样可以有效地减少编码的长度,从而实现数据的压缩。
三、实验过程和结果在本次实验中,我们选择了一段文本作为输入数据,通过统计每个字符的频率,构建了对应的哈夫曼树。
然后,根据哈夫曼树生成了字符的编码表,并将原始数据进行了编码。
最后,我们通过对编码后的数据进行解码,验证了哈夫曼编码的正确性。
实验结果显示,通过哈夫曼编码后,原始数据的长度明显减少,达到了较好的压缩效果。
同时,解码后的数据与原始数据完全一致,证明了哈夫曼编码的可靠性和正确性。
四、哈夫曼树的应用哈夫曼树在实际应用中有着广泛的用途。
其中,最典型的应用之一是数据压缩。
通过使用哈夫曼编码,可以将大量的数据压缩为较小的存储空间,从而节省了存储资源。
此外,哈夫曼树还被广泛应用于网络传输、图像处理等领域,提高了数据传输的效率和图像的质量。
五、对哈夫曼树的思考哈夫曼树作为一种经典的数据结构,其优势在于有效地减少了数据的冗余和存储空间的占用。
然而,随着技术的不断发展,现代的数据压缩算法已经不再局限于哈夫曼编码,而是采用了更为复杂和高效的算法。
因此,我们需要在实际应用中综合考虑各种因素,选择合适的压缩算法。
六、总结通过本次实验,我们深入了解了哈夫曼树的原理和应用。
哈夫曼编码作为一种重要的数据压缩算法,具有广泛的应用前景。
在实际应用中,我们需要根据具体情况选择合适的压缩算法,以达到最佳的压缩效果和性能。
哈夫曼树实验报告一、实验目的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. 熟悉哈夫曼编码和译码的实现过程。
4. 分析哈夫曼编码在数据压缩中的应用效果。
二、实验原理哈夫曼编码是一种基于字符频率的编码方法,它利用字符出现的频率来构造一棵最优二叉树(哈夫曼树),并根据该树生成字符的编码。
在哈夫曼树中,频率越高的字符对应的编码越短,频率越低的字符对应的编码越长。
这样,对于出现频率较高的字符,编码后的数据长度更短,从而实现数据压缩。
三、实验内容1. 构建哈夫曼树:- 统计待编码数据中每个字符出现的频率。
- 根据字符频率构建哈夫曼树,其中频率高的字符作为叶子节点,频率低的字符作为内部节点。
- 重复上述步骤,直到树中只剩下一个节点,即为哈夫曼树的根节点。
2. 生成哈夫曼编码:- 从哈夫曼树的根节点开始,对每个节点进行遍历,根据遍历方向(左子树为0,右子树为1)为字符分配编码。
- 将生成的编码存储在编码表中。
3. 编码和译码:- 使用生成的编码表对原始数据进行编码,将编码后的数据存储在文件中。
- 从文件中读取编码后的数据,根据编码表进行译码,恢复原始数据。
四、实验步骤1. 编写代码实现哈夫曼树的构建:- 定义节点结构体,包含字符、频率、左子树、右子树等属性。
- 实现构建哈夫曼树的核心算法,包括节点合并、插入等操作。
2. 实现编码和译码功能:- 根据哈夫曼树生成编码表。
- 编写编码函数,根据编码表对数据进行编码。
- 编写译码函数,根据编码表对数据进行译码。
3. 测试实验效果:- 选择一段文本数据,使用实验代码进行编码和译码。
- 比较编码前后数据的长度,分析哈夫曼编码的压缩效果。
五、实验结果与分析1. 哈夫曼树构建:- 成功构建了哈夫曼树,树中节点按照字符频率从高到低排列。
2. 哈夫曼编码:- 成功生成编码表,字符与编码的对应关系符合哈夫曼编码原理。
3. 编码与译码:- 成功实现编码和译码功能,编码后的数据长度明显缩短,译码结果与原始数据完全一致。
201*级数据结构实验报告哈夫曼树的建立姓名:***学号:***********班级:指导老师:***日期:201*.12.25一、实验题目及要求:实验题目:哈夫曼编码器设计实验要求:哈夫曼(Huffman)树与哈夫曼码1.输入一个文本,统计各字符出现的频度,输出结果;2.使用二叉链表或三叉链表作存储结构,构造哈夫曼(Huffman)树; 3.确定和输出各字符的哈夫曼码;4.输入一个由0和1组成的代码序列,翻译并输出与之对应的文本;操作提示:一个完整的系统应具有以下功能:(1)初始化: 从终端读入一段英文字符,统计每个字符出现的频率,建立赫夫曼树,并将该树存入某文件;(2)编码: 利用建好的赫夫曼树对各字符进行编码,用列表的形式显示在屏幕上,并将编码结果存入另一文件中;(3)解码: 利用保存的赫夫曼编码,对任意输入的0,1序列能正确解码。
二、实验分析及内容1、 存储结构a. 哈夫曼树的存储结构该程序使用一个静态三叉链表来存储哈夫曼树:weight LChild RChild Parent 2 -1 -1 4 3 -1 -1 4 6 -1 -1 5 9 -1 -1 6 5 1 1 5 11 2 2 6 2055-1b. 哈夫曼编码表的存储结构把每个字符data 及对应的编码code 用一个结点存储,将所有的结点存储在数组中:data Code Z 100 C 101 B 11 Ac. 录入字符串以及存储字符的数组a[]、b[]的获取:先将录入的字符串存在一个字符数组S[]中,然后遍历数组S[],先建立一个空的循环链表,然后再遍历数组S 的同时往链表里插入新的结点或者修改相应结点中的域值:0 1 2 3 4 5 60 1 2 3Data Weight Nextrrear2. 关键算法分析a.初始化哈夫曼树:用数组a[]初始化哈夫曼树:从0到n-1循环,分别对树中结点赋值:HTree[i].weight=a[i];HTree[i].lchild=-1;HTree[i].rchild=-1;HTree[i].parent=-1;b.创建哈夫曼树:(1)、从1——i中选择两个最小的结点:SelectMin(x,y,0,i);(2)、将选中的两个结点插入到树中:HTree[x].parent=HTree[y].parent=ii;HTree[ii].weight=HTree[x].weight+HTree[y].weight;HTree[ii].lchild=x;HTree[ii].rchild=y;HTree[ii].parent=-1;d.创建编码表:(1)、自下而上从叶子节点找到根节点,左孩子标识为‘0’,右孩子标识为‘1’,将‘0’、‘1’储存在编码表的code[]中;(2)、将code[]中的‘0’、‘1’进行倒序;e.编码:根据编码表,进行编码:for(int i=0;i<n;i++){ if(*s==HCodeTable[i].data){cout<<HCodeTable[i].code;s++;}}f.译码:输入一串‘0’、‘1’代码,根据编码表进行译码:(1)、如果是‘0’,则转到当前结点的左孩子:if(*s=='0') parent=HTree[parent].lchild;(2)、如果是‘1’,则转到当前结点的右孩子:else parent=HTree[parent].rchild;5、源程序:#include "stdio.h"typedef struct{float weight;int parent,lchild,rchild;}huftree;typedef struct{int bit[100];int length;}hufcode;huftree tree[100];//哈夫曼树hufcode code[100];//编码int num,m;//个数,编码最大长度void HufBuild(){int i,j,p1,p2;float s1,s2;printf("How: ");scanf("%d",&num);m=2*num-1;printf("请输入各个编码频率: ");for(i=0;i<num;i++){scanf("%f",&tree[i].weight);tree[i+num].parent=tree[i].parent=0;tree[i+num].lchild=tree[i].lchild=0;tree[i+num].rchild=tree[i].rchild=0;}for(i=num;i<m;i++){s1=s2=1; p1=p2=0;for(j=0;j<i;j++)if(tree[j].parent==0)if(tree[j].weight<s1){s2=s1; s1=tree[j].weight;p2=p1; p1=j;}else if(tree[j].weight<s2){s2=tree[j].weight;p2=j;}tree[p1].parent=tree[p2].parent=i;tree[i].weight=tree[p1].weight+tree[p2].weight;tree[i].lchild=p1; tree[i].rchild=p2;}}void CodePrint(){int i,j,p,k;printf("各个编码如下: \n");for(i=0;i<num;i++){printf("%6.2f",tree[i].weight);p=tree[i].parent;j=i;code[i].length=num-1;while(p!=0){if(tree[p].lchild==j) code[i].bit[code[i].length]=1;else code[i].bit[code[i].length]=0;code[i].length--;j=p;p=tree[p].parent;}printf(" ");for(k=code[i].length+1;k<num;k++)printf("%d",code[i].bit[k]);printf("\n");}}void main(){printf("输入一个要进行哈夫曼编码的字符串:"); gets();printf("如下是编码表:");HufBuild();pringtf("请输入一串0和1的代码");CodePrint();}3、运行结果三、实验小结1、虽然最终顺利的编完了程序,但是总的来说哈夫曼树还是很不容易的。
哈夫曼实验报告(附代码)以下是为大家整理的哈夫曼实验报告(附代码)的相关范文,本文关键词为哈夫曼,实验,报告,代码,,您可以从右上方搜索框检索更多相关文章,如果您觉得有用,请继续关注我们并推荐给您的好友,您可以在综合文库中查看更多范文。
哈弗曼编码/译码器一、程序的功能分析1.构造哈夫曼树及哈夫曼编码:从终端读入字符集大小n、n 个字符以及n个对应的权值,建立哈夫曼树;利用已经建好的哈夫曼树求每个叶结点的哈夫曼编码,并保存。
2.编码:利用已构造的哈夫曼编码对“明文”文件中的正文进行编码,然后将结果存入“密文”文件中。
3.译码:将“密文”文件中的0、1代码序列进行译码。
(读文件) 4.打印“密文”文件:将文件以紧凑格式显示在终端上,每行30个代码;同时,将此字符形式的编码文件保存。
5.打印哈夫曼树及哈夫曼编码:将已在内存中的哈夫曼树以凹入表形式显示在终端上,同时将每个字符的哈夫曼编码显示出来;并保存到文件。
二、基本要求分析1、输入输出的要求按提示内容从键盘输入命令,系统根据用户输入的需求在保证界面友好的前提下输出用户所需信息,并按要求保存文件,以便保存备份信息。
2、测试数据(1).令叶子结点个数n为4,权值集合为{1,3,5,7},字符集合为{A,b,c,D},且字符集与权值集合一一对应。
(2).令叶子结点个数n为7,权值集合为{12,6,8,18,3,20,2},字符集合为{A,b,c,D,e,F,g},且字符集与权值集合一一对应。
(3).请自行选定一段英文文本,统计给出的字符集,实际统计字符的频度,建立哈夫曼树,构造哈夫曼编码,并实现其编码和译码。
三、概要设计1.主模块的流程及各子模块的主要功能主函数负责提供选项功能,循环调控整个系统。
创建模块实现接收字符、权值、构建哈夫曼树,并保存文件,此功能是后续功能的基础。
编码模块实现利用已编好的哈夫曼树对每个字符进行哈夫曼编码,即对每个字符译出其密文代码,并保存文件。
实验六哈夫曼树的建立与操作一、实验要求和实验内容1、输入哈夫曼树叶子结点〔信息和权值〕2、由叶子结点生成哈夫曼树内部结点3、生成叶子结点的哈夫曼编码4、显示哈夫曼树结点顺序表二、实验要点:根据哈夫曼算法,建立哈夫曼树时,可以将哈夫曼树定义为一个构造型的一维数组HuffTree,保存哈夫曼树中各结点的信息,每个结点包括:权值、左孩子、右孩子、双亲,如图5-4所示。
由于哈夫曼树中共有2n-1个结点,并且进展n-1次合并操作,所以该数组的长度为2n-1。
构造哈夫曼树的伪代码如下:在哈夫曼树中,设左分支为0,右分支为1,从根结点出发,遍历整棵哈夫曼树,求得各个叶子结点所表示字符的哈夫曼编码。
三、.函数的功能说明及算法思路BTreeNode* CreateHuffman(ElemType a[],int n)//构造哈夫曼树1.对给定n个权值{a1,a2,…,an}的叶子结点,构成具有n棵二叉树的森林F={T1,T2,…,Tn}, 其中每棵二叉树Ti只有一个权值为ai的根结点,其左右子树为空。
2.在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且新的二叉树的根结点的权值为其左右子树上根结点的权值之和。
3.从F中删除构成新树的两棵树,并把新树参加到F中。
4.重复 2、3两步,直到F只有一棵树为止。
则F中的树就是哈夫曼树。
void PrintBTree(BTreeNode *BT)//以广义表形式输出哈夫曼树主要用到了递归的思想。
void HuffManCoding(BTreeNode *BT, int len)//求哈夫曼编码构造一棵二叉树,左分支标识为0,右分支标识为1,把 n 个字符看成是一棵树的 n个叶子结点,把从根结点到每个叶子结点路径上的分支标识序列作为字符的编码,则得到哈夫曼编码。
四、实验步骤和提示1、编写有关哈夫曼树操作的函数:①构造哈夫曼树 BTreeNode * CreateHuffman(ElemType a[],int n);②以广义表形式输出哈夫曼树 void PrintBTree(BTreeNode *BT);③求哈夫曼编码 void HuffManCoding(BTreeNode *BT, int len)。
2009级数据结构实验报告实验名称:实验3——哈夫曼树学生姓名:陈家斌班级:2009211121班内序号:16学号:09210619日期:2010年12月3日1.实验要求【实验目的】通过选择下面两个题目之一进行实现,掌握如下内容:➢掌握二叉树基本操作的实现方法➢了解赫夫曼树的思想和相关概念➢学习使用二叉树解决实际问题的能力【题目】利用二叉树结构实现赫夫曼编/解码器。
【基本要求】1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立赫夫曼树2、建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每个字符的编码输出。
3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。
4、译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译码,并输出译码结果。
5、打印(Print):以直观的方式打印赫夫曼树(选作)6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。
【测试数据】I love data Structure, I love Computer。
I will try my best to study data Structure.提示:1、用户界面可以设计为“菜单”方式:能够进行交互。
2、根据输入的字符串中每个字符出现的次数统计频度,对没有出现的字符一律不用编码。
【代码要求】1、必须要有异常处理,比如删除空链表时需要抛出异常;2、保持良好的编程的风格:➢代码段与段之间要有空行和缩近➢标识符名称应该与其代表的意义一致➢函数名之前应该添加注释说明该函数的功能➢关键代码应说明其功能3、递归程序注意调用的过程,防止栈溢出2. 程序分析【算法实现】程序第一遍统计原数据中各字符出现的频率,利用得到的频率值创建哈夫曼树,并把树的信息保存起来,以便解压时创建同样的哈夫曼树进行解压;第二遍,根据第一遍扫描得到的哈夫曼树进行编码,并把编码后的码字存储。
数据结构实验报告:哈夫曼树及哈夫曼编码一、实验目的1. 理解哈夫曼树及哈夫曼编码的概念和原理;2. 掌握C语言中哈夫曼树及哈夫曼编码的实现方法;3. 分析和讨论哈夫曼编码在实际应用中的优势和不足。
二、实验内容和步骤1. 哈夫曼树的构建1.1 通过C语言实现哈夫曼树的构建算法;1.2 输入一组权值,按哈夫曼树构建规则生成哈夫曼树;1.3 输出生成的哈夫曼树结构,并进行可视化展示。
2. 哈夫曼编码的实现2.1 设计哈夫曼编码的实现算法;2.2 对指定字符集进行编码,生成哈夫曼编码表;2.3 对给定字符串进行哈夫曼编码,并输出编码结果。
三、实验过程及结果1. 哈夫曼树的构建在C语言中,通过定义结构体和递归算法实现了哈夫曼树的构建。
根据输入的权值,依次选择权值最小的两个节点构建新的父节点,直至构建完成整棵哈夫曼树。
通过调试和可视化展示,确认了程序正确实现了哈夫曼树的构建。
2. 哈夫曼编码的实现经过分析和设计,利用哈夫曼树的特点实现了哈夫曼编码的算法。
根据生成的哈夫曼树,递归地生成字符对应的哈夫曼编码,并输出编码结果。
对指定的字符串进行了编码测试,验证了哈夫曼编码的正确性和有效性。
四、实验结果分析1. 哈夫曼编码在数据传输和存储中具有较高的压缩效率和可靠性,能够有效减少数据传输量和存储空间;2. 哈夫曼树及哈夫曼编码在通信领域、数据压缩和加密等方面有着广泛的应用和重要意义;3. 在实际应用中,哈夫曼编码的构建和解码算法需要较大的时间和空间复杂度,对于大规模数据的处理存在一定的局限性。
五、实验总结通过本次实验,深入理解了哈夫曼树及哈夫曼编码的理论知识,并掌握了C语言中实现哈夫曼树及哈夫曼编码的方法。
对哈夫曼编码在实际应用中的优势和局限性有了更深入的认识,这对今后的学习和工作有着积极的意义。
六、参考文献1. 《数据结构(C语言版)》,严蔚敏赵现军著,清华大学出版社,2012年;2. 《算法导论》,Thomas H. Cormen 等著,机械工业出版社,2006年。
数据结构哈夫曼树实验报告一、实验目的本次实验的主要目的是深入理解和掌握哈夫曼树的数据结构及其相关算法,并通过实际编程实现来提高对数据结构的应用能力和编程技能。
二、实验环境本次实验使用的编程环境为具体编程语言名称,操作系统为具体操作系统名称。
三、实验原理哈夫曼树,又称最优二叉树,是一种带权路径长度最短的二叉树。
其基本原理是通过构建一棵二叉树,使得权值较大的节点距离根节点较近,权值较小的节点距离根节点较远,从而达到带权路径长度最小的目的。
在构建哈夫曼树的过程中,首先需要将所有的节点按照权值从小到大进行排序。
然后,选取权值最小的两个节点作为左右子树,构建一个新的父节点,该父节点的权值为左右子节点权值之和。
重复这个过程,直到所有的节点都被构建到哈夫曼树中。
哈夫曼编码是基于哈夫曼树的一种编码方式。
对于每个叶子节点,从根节点到该叶子节点的路径上,向左的分支编码为 0,向右的分支编码为 1,这样就可以得到每个叶子节点的哈夫曼编码。
四、实验步骤1、定义节点结构体```ctypedef struct HuffmanNode {char data;int weight;struct HuffmanNode left;struct HuffmanNode right;} HuffmanNode;```2、实现节点排序函数```cvoid sortNodes(HuffmanNode nodes, int n) {for (int i = 0; i < n 1; i++){for (int j = 0; j < n i 1; j++){if (nodesj>weight > nodesj + 1>weight) {HuffmanNode temp = nodesj;nodesj = nodesj + 1;nodesj + 1 = temp;}}}}```3、构建哈夫曼树```cHuffmanNode buildHuffmanTree(HuffmanNode nodes, int n) {while (n > 1) {sortNodes(nodes, n);HuffmanNode left = nodes0;HuffmanNode right = nodes1;HuffmanNode parent =(HuffmanNode )malloc(sizeof(HuffmanNode));parent>data ='\0';parent>weight = left>weight + right>weight;parent>left = left;parent>right = right;nodes0 = parent;nodes1 = nodesn 1;n;}return nodes0;}```4、生成哈夫曼编码```cvoid generateHuffmanCodes(HuffmanNode root, int codes, int index) {if (root>left) {codesindex = 0;generateHuffmanCodes(root>left, codes, index + 1);}if (root>right) {codesindex = 1;generateHuffmanCodes(root>right, codes, index + 1);}if (!root>left &&!root>right) {printf("%c: ", root>data);for (int i = 0; i < index; i++){printf("%d", codesi);}printf("\n");}}```5、主函数```cint main(){HuffmanNode nodes5 ={(HuffmanNode )malloc(sizeof(HuffmanNode)),(HuffmanNode )malloc(sizeof(HuffmanNode)),(HuffmanNode )malloc(sizeof(HuffmanNode)),(HuffmanNode )malloc(sizeof(HuffmanNode)),(HuffmanNode )malloc(sizeof(HuffmanNode))};nodes0>data ='A';nodes0>weight = 5;nodes1>data ='B';nodes1>weight = 9;nodes2>data ='C';nodes2>weight = 12;nodes3>data ='D';nodes3>weight = 13;nodes4>data ='E';nodes4>weight = 16;HuffmanNode root = buildHuffmanTree(nodes, 5);int codes100;generateHuffmanCodes(root, codes, 0);return 0;}```五、实验结果与分析通过运行上述程序,得到了每个字符的哈夫曼编码:A: 00B: 01C: 10D: 110E: 111分析实验结果可以发现,权值较小的字符A 和B 对应的编码较短,而权值较大的字符D 和E 对应的编码较长。
哈夫曼树编码实验报告、数据结构课程设计报告题目:哈夫曼编码/译码学院数学与信息科学学院学科门类理科专业数学类学号2013433033姓名田娟2014年12 月30日目录一、需求分析1.程序的功能 (3)2.输入输出的要求 (3)3.测试数据 (3)二、概要设计1.本程序所用的抽象数据类型的定义 (3)2.主程序模块 (3)3.主模块的流程及各子模块的主要功能 (4)4.模块之间的层次关系 (4)三、详细设计1.采用c语言定义相关的数据类型 (4)2. 伪码算法 (5)四、调试分析1.调试中遇到的问题及对问题的解决方法 (15)五、使用说明及测试结果1.建立哈夫曼树,输入叶子结点个数,权值,字符集 (15)2.编码 (15)3.译码 (16)4.显示码文 (16)5.显示哈夫曼树 (16)六、源程序一、需求分析1.程序的功能;哈夫曼编码是一种应用广泛而有效的数据压缩技术。
利用哈夫曼编码进行通信可以大大提高信道利用率,加快信息传输速度,降低传输成本。
数据压缩的过程称为编码,解压缩的过程称为译码。
进行信息传递时,发送端通过一个编码系统对待传数据(明文)预先编码,而接收端将传来的数据(密文)进行译码。
2.输入输出的要求;:2.1.构造哈夫曼树及哈夫曼编码:从终端读入字符集大小n、n个字符以及n个对应的权值,建立哈夫曼树;利用已经建好的哈夫曼树求每个叶结点的哈夫曼编码,并保存。
2.2编码:利用已构造的哈夫曼编码对“明文”文件中的正文进行编码,然后将结果存入“密文”文件中。
2.3.译码:将“密文”文件中的0、1代码序列进行译码。
2.4.打印“密文”文件:将文件以紧凑格式显示在终端上,每行30个代码;同时,将此字符形式的编码文件保存。
2.5.打印哈夫曼树及哈夫曼编码:将已在内存中的哈夫曼树以凹入表形式显示在终端上,同时将每个字符的哈夫曼编码显示出来;并保存到文件。
3.测试数据。
3.1.令叶子结点个数N为4,权值集合为{1,3,5,7},字符集合为{A,B,C,D},且字符集与权值集合一一对应。
哈夫曼实验报告总结哈夫曼编码是一种用于数据压缩的有效算法,它能够将出现频率较高的字符用较短的编码表示,而将出现频率较低的字符用较长的编码表示,从而实现数据的压缩。
本次实验的目的是通过实现哈夫曼编码算法,深入理解哈夫曼编码的原理和应用,并通过实验证明其压缩效果。
在实验中,我们首先需要计算每个字符在给定文本中的出现频率。
通过统计文本中的字符频率,我们可以构建出一个字符频率表,其中每个字符和其对应的频率成对出现。
接下来,根据字符频率表,我们需要构建哈夫曼树。
哈夫曼树是一种特殊的二叉树,它的叶子节点对应于字符,而非叶子节点对应于字符的编码。
构建哈夫曼树的过程是通过将频率较小的字符不断相加作为新的频率节点,直到最终构建出完整的哈夫曼树。
构建哈夫曼树的过程是一个递归的过程,可以通过优先队列或最小堆来实现。
构建完哈夫曼树后,我们可以根据哈夫曼树为每个字符生成对应的编码。
在哈夫曼树中,从根节点到叶子节点的路径表示字符的编码,路径上的左-右方向分别表示0和1。
生成编码的过程是通过遍历哈夫曼树的路径,并记录经过的方向来实现的。
为了更高效地生成编码,可以使用哈希表或者数组来存储每个字符对应的编码。
实验中,我们将生成的哈夫曼编码应用于数据的压缩。
通过将文本中的每个字符替换为其对应的哈夫曼编码,并将生成的编码串连接起来,可以实现对数据的压缩。
压缩效果取决于字符的频率分布情况,频率更高的字符会得到较短的编码,而频率较低的字符会得到较长的编码。
在本次实验中,我们通过分别计算原始文本和压缩后文本的字节数,计算了压缩率。
压缩率的计算公式为:压缩率 = (1 - 压缩后字节数 / 原始字节数) * 100%。
通过实验数据的对比,我们可以发现,哈夫曼编码能够有效地减小数据的存储空间,实现较高的压缩率。
通过本次实验,我深入学习了哈夫曼编码的原理和实现方法。
哈夫曼编码是一种非常有效的数据压缩算法,广泛应用于各类数据压缩工具和通信传输中。
哈夫曼树实验报告 Company number:【0089WT-8898YT-W8CCB-BUUT-202108】
计算机科学与技术学院数据结构实验报告
班级 2014级计算机1班学号姓名张建华成绩
实验项目简单哈夫曼编/译码的设计与实现实验日期一、实验目的
本实验的目的是进一步理解哈夫曼树的逻辑结构和存储结构,进一步提高使用理论知识指导解决实际问题的能力。
二、实验问题描述
利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码,此实验即设计这样的一个简单编/码系统。
系统应该具有如下的几个功能:
1、接收原始数据。
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件中。
2、编码。
利用已建好的哈夫曼树(如不在内存,则从文件中读入),对文件中的正文进行编码,然后将结果存入文件中。
3、译码。
利用已建好的哈夫曼树将文件中的代码进行译码,结果存入文件中。
4、打印编码规则。
即字符与编码的一一对应关系。
5、打印哈夫曼树,
将已在内存中的哈夫曼树以直观的方式显示在终端上。
三、实验步骤
1、实验问题分析
1、构造哈夫曼树时使用静态链表作为哈夫曼树的存储。
在构造哈夫曼树时,设计一个结构体数组HuffNode保存哈夫曼树中各结点的信息,根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有2n-1个结点,所以数组HuffNode的大小设置为2n-1,描述结点的数据类型为:
Typedef strcut
{
Int weight;/*结点权值*/
Int parent;
Int lchild;
Int rchild;
}HNodeType;
2、求哈夫曼编码时使用一维结构数组HuffCode作为哈夫曼编码信息的存储。
求哈夫曼编码,实质上就是在已建立的哈夫曼树中,从叶子结点开始,沿结点的双亲链域回退到根结点,没回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值,由于一个字符的哈夫曼编码是从根结点到相应叶子结点所经过的路
径上各分支所组成的0、1序列,因此先得到的分支代码为所求编码的低位码,后得到的分支代码位所求编码的高位码,所以设计如下数据类型:
#define MAXBIT 10
Typedef struct
{
Int bit[MAXBIT];
Int start;
}HCodeType;
3、文件、和。
2、功能(函数)设计
(1)、初始化功能模块。
此功能模块的功能为从键盘接收字符集大小n,以及n个字符和n个权值。
(2)、建立哈夫曼树的功能模块。
此模块功能为使用1中得到的数据按照教材中的构造哈夫曼树的算法构造哈夫曼树,即将HuffNode数组中的各个位置的各个域都添上相关的值,并将这个结构体数组存于文件中。
(3)、建立哈夫曼编码的功能模块。
此模块功能为从文件中读入相关的字符信息进行哈夫曼编码,然后将结果存入中,同时将字符与0、1代码串的一一对应关系打印到屏幕上。
(4)、译码的功能模块。
此模块功能为接收需要译码的0、1代码串,按照3中建立的编码规则将其翻译成字符集中字符所组成的字符串形式,存入文件,同时将翻译的结果在屏幕上打印输出。
(5)、打印哈夫曼树的功能模块。
此模块功能为从HuffNode数组中读入相关的结点信息,以图形的方式将各个结点以及叶子结点的权值和左分支上的0和右分支上的1画出来。
四、实验结果(程序)及分析
1、实验主要代码
typedef struct /*结点结构体*/
{
string hfmstr; /*结点内容*/
int weight; /*结点权值*/
int parent;
int lchild;
int rchild;
}HNodeType;
typedef struct /* 编码结构体 */
{
int bit[MAXBIT];
int start;
}HCodeType;
void Create_HuffMTree(HNodeType HFMTree[],int n) /*创建哈夫曼树*/ {
int m1,x1,m2,x2;
int i,j;
for(i=0;i<2*n-1;i++)
{
HFMTree[i].hfmstr="";
HFMTree[i].weight=0;
HFMTree[i].parent=-1;
HFMTree[i].lchild=-1;
HFMTree[i].rchild=-1;
}
for(i=0;i<n;i++)
{
cout<<"请输入第"<<i+1<<"个权值"<<endl;
cin>>HFMTree[i].weight;
cout<<"请输入对应字符"<<endl;
cin>>HFMTree[i].hfmstr;
}
for(i=0;i<n-1;i++)
{
x1=x2=MAXVALUE;
m1=m2=0;
for(j=0;j<n+i;j++)
{
if(HFMTree[j].parent==-1&&HFMTree[j].weight<x1)
{
x2=x1;
m2=m1;
x1=HFMTree[j].weight;
m1=j;
}
else if(HFMTree[j].parent==-1&&HFMTree[j].weight<x2)
{
x2=HFMTree[j].weight;
m2=j;
}
}
HFMTree[m1].parent=n+i;
HFMTree[m2].parent=n+i;
HFMTree[n+i].weight=HFMTree[m1].weight+HFMTree[m2].weight;
HFMTree[n+i].lchild=m1;
HFMTree[n+i].rchild=m2;
}
cout<<"创建哈夫曼树成功!"<<endl;
}
void HaffmanCode(HNodeType HFMTree[],HCodeType HuffCode[],int n) /*构建哈夫曼编码*/
{
HCodeType cd;
int i,j,c,p;
for(i=0;i<n;i++)
{
=n-1;
c=i;
p=HFMTree[c].parent;
while(p!=-1)
{
if(HFMTree[p].lchild==c)
[]=0;
else
[]=1;
;
c=p;
p=HFMTree[c].parent;
}
for(j=+1;j<n;j++)
HuffCode[i].bit[j] = [j];
HuffCode[i].start = ;
}
}
void decodeing(char string[],HNodeType HFMTree[],int n) /*解码*/
{
int i,tmp=0,code[1024];
int m=2*n-1;
char *nump;
char num[1024];
for(i=0;i<strlen(string);i++)
{
if(string[i]=='0')
num[i]=0;
else
num[i]=1;
}
i=0;
nump=&num[0];
while(nump<(&num[strlen(string)]))
{
tmp=m-1;
while((HFMTree[tmp].lchild!=-1)&&(HFMTree[tmp].rchild!=-1)) {
if(*nump==0)
{
tmp=HFMTree[tmp].lchild ;
}
else
tmp=HFMTree[tmp].rchild;
nump++;
}
cout<<HFMTree[tmp].hfmstr; }
cout<<endl;
}
2、测试数据与输出。