数据结构哈夫曼编码实验报告
哈夫曼编码实验报告总结.doc
哈夫曼编码实验报告实验一哈夫曼编码一、实验目的1、掌握哈夫曼编码原理;2、熟练掌握哈夫曼树的生成方法;3、理解数据编码压缩和译码输出编码的实现。
二、实验要求实现哈夫曼编码和译码的生成算法。
三、实验内容先统计要压缩编码的文件中的字符字母出现的次数,按字符字母和空格出现的概率对其进行哈夫曼编码,然后读入要编码的文件,编码后存入另一个文件;接着再调出编码后的文件,并对其进行译码输出,最后存入另一个文件中。
五、实验原理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 编码与之唯一对应,并且任何编码没有前部分是同其他完整编码一样的。
六、实验流程① 初始化,统计文本文件中各字符的个数作为权值 ,生成哈夫曼树;② 根据符号概率的大小按由大到小顺序对符号进行排序;③把概率最小的两个符号组成一个节点;④重复步骤( 2)(3),直到概率和为1;⑤从根节点开始到相应于每个符号的“树叶”,概率大的标“0”,概率小的标“1”;⑥从根节点开始,对符号进行编码;⑦ 译码时流程逆向进行,从文件中读出哈夫曼树 ,并利用哈夫曼树将编码序列解码。
数据结构哈夫曼编码实验报告
数据结构哈夫曼编码实验报告一、实验目的:通过哈夫曼编、译码算法的实现,巩固二叉树及哈夫曼树相关知识的理解掌握,训练学生运用所学知识,解决实际问题的能力。
二、实验内容:已知每一个字符出现的频率,构造哈夫曼树,并设计哈夫曼编码。
1、从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树。
2、打印每一个字符对应的哈夫曼编码。
3、对从终端读入的字符串进行编码,并显示编码结果。
4、对从终端读入的编码串进行译码,并显示译码结果。
三、实验方案设计:(对基本数据类型定义要有注释说明,解决问题的算法思想描述要完整,算法结构和程序功能模块之间的逻辑调用关系要清晰,关键算法要有相应的流程图,对算法的时间复杂度要进行分析)1、算法思想:(1)构造两个结构体分别存储结点的字符及权值、哈夫曼编码值:(2)读取前n个结点的字符及权值,建立哈夫曼树:(3)根据哈夫曼树求出哈夫曼编码:2、算法时间复杂度:(1)建立哈夫曼树时进行n到1次合并,产生n到1个新结点,并选出两个权值最小的根结点:O(n²);(2)根据哈夫曼树求出哈夫曼编码:O(n²)。
(3)读入电文,根据哈夫曼树译码:O(n)。
四、该程序的功能和运行结果:(至少有三种不同的测试数据和相应的运行结果,充分体现该程序的鲁棒性)1、输入字符A,B,C,D,E,F及其相应权值16、12、9、30、6、3。
2、输入字符F,E,N,G,H,U,I及其相应权值30、12、23、22、12、7、9。
3、输入字符A,B,C,D,E,F,G,H,I,G及其相应权值19、23、25、18、12、67、23、9、32、33。
数据结构哈夫曼编码实验报告
数据结构哈夫曼编码实验报告数据结构哈夫曼编码实验报告1·实验目的1·1 理解哈夫曼编码的基本原理1·2 掌握哈夫曼编码的算法实现方式1·3 熟悉哈夫曼编码在数据压缩中的应用2·实验背景2·1 哈夫曼编码的概念和作用2·2 哈夫曼编码的原理和算法2·3 哈夫曼编码在数据压缩中的应用3·实验环境3·1 硬件环境:计算机、CPU、内存等3·2 软件环境:编程语言、编译器等4·实验过程4·1 构建哈夫曼树4·1·1 哈夫曼树的构建原理4·1·2 哈夫曼树的构建算法4·2 哈夫曼编码4·2·1 哈夫曼编码的原理4·2·2 哈夫曼编码的算法4·3 实现数据压缩4·3·1 数据压缩的概念和作用4·3·2 哈夫曼编码在数据压缩中的应用方法5·实验结果5·1 构建的哈夫曼树示例图5·2 哈夫曼编码表5·3 数据压缩前后的文件大小对比5·4 数据解压缩的正确性验证6·实验分析6·1 哈夫曼编码的优点和应用场景分析6·2 数据压缩效果的评估和对比分析6·3 实验中遇到的问题和解决方法7·实验总结7·1 实验所获得的成果和收获7·2 实验中存在的不足和改进方向7·3 实验对于数据结构学习的启示和意义附件列表:1·实验所用的源代码文件2·实验中用到的测试数据文件注释:1·哈夫曼编码:一种用于数据压缩的编码方法,根据字符出现频率构建树形结构,实现高频字符用较短编码表示,低频字符用较长编码表示。
2·哈夫曼树:由哈夫曼编码算法构建的一种特殊的二叉树,用于表示字符编码的结构。
数据结构 哈夫曼编码实验报告
数据结构哈夫曼编码实验报告数据结构哈夫曼编码实验报告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:实验目的本实验旨在:a:了解哈夫曼编码算法的基本原理;b:实现哈夫曼编码算法,并将其应用于对文本进行压缩;c:评估哈夫曼编码算法在不同文本数据上的性能。
二、实验内容1:哈夫曼编码原理介绍2:哈夫曼编码的实现思路a:构建哈夫曼树b:哈夫曼编码表c:对文本进行编码和解码3:实验环境介绍a:硬件环境b:软件环境4:实验步骤详解a:构建哈夫曼树的实现方法b:哈夫曼编码表的实现方法c:文本编码和解码的实现方法5:实验数据与结果分析a:不同文本数据的压缩结果对比 b:压缩性能的评估指标6:实验心得与建议a:实验过程中遇到的问题b:改进与优化方向三、实验结果与分析1:实验数据a:不同文本数据的大小与内容b:压缩率等性能指标数据2:实验结果分析a:不同文本数据对压缩效果的影响b:压缩率与文本数据的关系c:哈夫曼编码的运行时间分析四、结论根据实验结果和分析,可以得出以下结论:1:哈夫曼编码算法能够有效地减少文本数据的存储空间。
2:不同文本数据的压缩率存在差异,与文本的特性有关。
3:哈夫曼编码算法的运行时间与文本数据的长度成正比关系。
附件:1:实验源代码2:实验数据和结果法律名词及注释:1:无损数据压缩:指通过编码和解码过程,在不导致数据信息损失的情况下减少数据量。
2:哈夫曼编码:一种变长编码方式,通过更少的编码长度来表示频率较高的字符,从而达到减少编码长度的目的。
数据结构哈夫曼编码实验报告
数据结构哈夫曼编码实验报告【正文】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. 构建哈夫曼树首先,我们需要根据给定的字符频率表构建哈夫曼树。
哈夫曼树是一种特殊的二叉树,其叶子节点表示字符,而非叶子节点表示字符的编码。
构建哈夫曼树的过程如下:1. 根据给定的字符频率表,将每个字符视为一个节点,并按照频率从小到大的顺序排列。
2. 将频率最小的两个节点合并为一个新节点,并将其频率设置为两个节点的频率之和。
这个新节点成为新的子树的根节点。
3. 将新节点插入到原来的节点列表中,并继续按照频率从小到大的顺序排序。
4. 重复步骤2和步骤3,直到只剩下一个节点,这个节点即为哈夫曼树的根节点。
2. 哈夫曼编码表在构建完哈夫曼树后,我们需要根据哈夫曼树每个字符的哈夫曼编码表。
哈夫曼编码表是一个字典,用于存储每个字符对应的编码。
哈夫曼编码表的过程如下:1. 从哈夫曼树的根节点出发,遍历整个树。
2. 在遍历的过程中,维护一个路径,用于记录到达每个字符节点的路径,0表示左子树,1表示右子树。
3. 当到达一个字符节点时,将路径上的编码存储到哈夫曼编码表中对应的字符键下。
3. 压缩数据有了哈夫曼编码表后,我们可以使用哈夫曼编码对数据进行压缩。
将原本以字符表示的数据,转换为使用哈夫曼编码表示的二进制数据。
压缩数据的过程如下:1. 将待压缩的数据转换为对应的哈夫曼编码,将所有的编码连接成一个字符串。
2. 将该字符串表示的二进制数据存储到文件中,同时需要保存哈夫曼编码表以便解压时使用。
实验结果通过实验,我们成功实现了哈夫曼编码的构建和使用。
数据结构哈夫曼编码实验报告
数据结构哈夫曼编码实验报告
第一章实验目的
本实验旨在掌握哈夫曼编码的原理和实现方法,并通过编写代码实现一个简单的哈夫曼编码程序。
第二章实验内容
1.理解哈夫曼编码的基本概念和原理。
2.设计并实现一个哈夫曼编码的数据结构。
3.实现哈夫曼编码的压缩和解压缩功能。
4.通过实验验证哈夫曼编码的效果和压缩比。
第三章实验步骤
1.确定实验所需的编程语言和开发环境。
2.定义并实现哈夫曼编码的数据结构。
3.实现哈夫曼编码的压缩和解压缩算法。
4.设计实验样例数据,进行测试和验证。
5.分析实验结果,计算压缩比。
第四章实验结果与分析
1.实验样例数据:________提供一段文本,统计字符出现的频率,并进行哈夫曼编码。
2.实验结果:________展示压缩后的编码结果,计算压缩比。
3.分析:________分析实验结果,讨论哈夫曼编码的效果和优劣。
第五章实验总结与感想
本次实验深入了解了哈夫曼编码的原理和实现方法,通过编写代码实现哈夫曼编码的压缩和解压缩功能。
实验结果表明,哈夫曼编码能够有效地减小数据的存储空间,提高了数据传输的效率。
第六章本文档涉及附件
本实验报告所涉及到的附件包括:________
1.实验代码文件:________.c
2.实验样例数据文件:________.txt
第七章法律名词及注释
1.哈夫曼编码:________一种用于无损数据压缩的编码方法,通过对频率高的字符赋予较短的编码,对频率低的字符赋予较长的编码,从而实现压缩数据的目的。
哈夫曼实验报告
一、实验目的1. 理解哈夫曼编码的基本原理和重要性。
2. 掌握哈夫曼树的构建方法。
3. 熟悉哈夫曼编码和译码的实现过程。
4. 分析哈夫曼编码在数据压缩中的应用效果。
二、实验原理哈夫曼编码是一种基于字符频率的编码方法,它利用字符出现的频率来构造一棵最优二叉树(哈夫曼树),并根据该树生成字符的编码。
在哈夫曼树中,频率越高的字符对应的编码越短,频率越低的字符对应的编码越长。
这样,对于出现频率较高的字符,编码后的数据长度更短,从而实现数据压缩。
三、实验内容1. 构建哈夫曼树:- 统计待编码数据中每个字符出现的频率。
- 根据字符频率构建哈夫曼树,其中频率高的字符作为叶子节点,频率低的字符作为内部节点。
- 重复上述步骤,直到树中只剩下一个节点,即为哈夫曼树的根节点。
2. 生成哈夫曼编码:- 从哈夫曼树的根节点开始,对每个节点进行遍历,根据遍历方向(左子树为0,右子树为1)为字符分配编码。
- 将生成的编码存储在编码表中。
3. 编码和译码:- 使用生成的编码表对原始数据进行编码,将编码后的数据存储在文件中。
- 从文件中读取编码后的数据,根据编码表进行译码,恢复原始数据。
四、实验步骤1. 编写代码实现哈夫曼树的构建:- 定义节点结构体,包含字符、频率、左子树、右子树等属性。
- 实现构建哈夫曼树的核心算法,包括节点合并、插入等操作。
2. 实现编码和译码功能:- 根据哈夫曼树生成编码表。
- 编写编码函数,根据编码表对数据进行编码。
- 编写译码函数,根据编码表对数据进行译码。
3. 测试实验效果:- 选择一段文本数据,使用实验代码进行编码和译码。
- 比较编码前后数据的长度,分析哈夫曼编码的压缩效果。
五、实验结果与分析1. 哈夫曼树构建:- 成功构建了哈夫曼树,树中节点按照字符频率从高到低排列。
2. 哈夫曼编码:- 成功生成编码表,字符与编码的对应关系符合哈夫曼编码原理。
3. 编码与译码:- 成功实现编码和译码功能,编码后的数据长度明显缩短,译码结果与原始数据完全一致。
哈弗曼树实验报告(3篇)
一、实验目的1. 理解并掌握哈弗曼树的构建原理。
2. 学会使用哈弗曼树进行数据编码和解码。
3. 了解哈弗曼编码在数据压缩中的应用。
二、实验原理哈弗曼树(Huffman Tree)是一种带权路径长度最短的二叉树,用于数据压缩。
其基本原理是:将待编码的字符集合按照出现频率从高到低排序,构造一棵二叉树,使得叶子节点代表字符,内部节点代表编码,权值代表字符出现的频率。
通过这棵树,可以生成每个字符的编码,使得编码的平均长度最小。
三、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019四、实验步骤1. 构建哈弗曼树(1)创建一个结构体`HuffmanNode`,包含字符、权值、左子树和右子树指针。
```cppstruct HuffmanNode {char data;int weight;HuffmanNode left;HuffmanNode right;};(2)定义一个函数`HuffmanTree()`,用于创建哈弗曼树。
```cppHuffmanNode HuffmanTree(std::vector<char>& chars, std::vector<int>& weights) {// 创建初始二叉树std::vector<HuffmanNode> trees;for (int i = 0; i < chars.size(); ++i) {trees.push_back(new HuffmanNode{chars[i], weights[i], nullptr, nullptr});}// 构建哈弗曼树while (trees.size() > 1) {// 选择两个权值最小的节点auto it1 = std::min_element(trees.begin(), trees.end(),[](HuffmanNode a, HuffmanNode b) {return a->weight < b->weight;});auto it2 = std::next(it1);HuffmanNode parent = new HuffmanNode{0, it1->weight + it2->weight, it1, it2};// 删除两个子节点trees.erase(it1);trees.erase(it2);// 将父节点添加到二叉树集合中trees.push_back(parent);}// 返回哈弗曼树根节点return trees[0];}```2. 生成哈弗曼编码(1)定义一个函数`GenerateCodes()`,用于生成哈弗曼编码。
数据结构 哈夫曼编码实验报告(2023版)
数据结构哈夫曼编码实验报告实验目的:本实验旨在了解和实现哈夫曼编码算法,通过将字符转换为对应的哈夫曼编码来实现数据的压缩和解压缩。
一、引言1.1 背景介绍哈夫曼编码是一种基于字符出现频率的编码方法,通过使用不等长编码来表示不同字符,从而实现数据的高效压缩。
该编码方法在通信、存储等领域有着广泛的应用。
1.2 目标本实验的目标是实现哈夫曼编码算法,通过对给定文本进行编码和解码,验证哈夫曼编码的有效性和可靠性。
二、实验过程2.1 数据结构设计在实现哈夫曼编码算法时,我们需要设计合适的数据结构来存储字符和对应的编码。
常用的数据结构包括树和哈希表。
我们将使用二叉树作为数据结构来表示字符的编码。
2.2 构建哈夫曼树哈夫曼树是由给定字符集合构建而成的最优二叉树。
构建哈夫曼树的过程分为两步:首先根据字符出现频率构建叶子节点,然后通过合并叶子节点和父节点构造哈夫曼树。
2.3 哈夫曼编码表根据构建好的哈夫曼树,我们可以对应的哈夫曼编码表。
哈夫曼编码表由字符和对应的编码组成,可以用于字符的编码和解码。
2.4 文本压缩利用的哈夫曼编码表,我们可以对给定的文本进行压缩。
将文本中的字符逐个替换为对应的哈夫曼编码,从而实现数据的压缩。
2.5 文本解压缩对压缩后的数据进行解压缩时,我们需要利用的哈夫曼编码表,将哈夫曼编码逐个替换为对应的字符,从而还原出原始的文本数据。
三、实验结果我们使用不同长度、不同频率的文本进行了实验。
实验结果表明,哈夫曼编码在数据压缩方面有着显著的效果,可以大大减小数据存储和传输的开销。
四、实验总结通过本实验,我们深入理解了哈夫曼编码算法的原理和实现过程,掌握了数据的压缩和解压缩技术。
哈夫曼编码作为一种经典的数据压缩算法,具有重要的理论意义和实际应用价值。
附件:本文档附带哈夫曼编码实验的源代码和实验数据。
法律名词及注释:在本文档中,涉及的法律名词和注释如下:1.哈夫曼编码:一种数据压缩算法,用于将字符转换为可变长度的编码。
数据结构 哈夫曼编码实验报告
数据结构哈夫曼编码实验报告数据结构实验报告----------1-实验目的----------本实验的目的是通过实现哈夫曼编码算法,加深对数据结构中树和堆的理解,以及掌握相关的编程技巧。
2-实验内容----------2-1 算法简介----------哈夫曼编码是一种无损压缩算法,通过根据字符出现的频率构建一颗二叉树,并将出现频率较高的字符编码为较短的二进制串,进而实现压缩的目的。
在本实验中,我们需要实现以下功能:●构建哈夫曼树●字符编码表●对给定的字符串进行编码●对给定的二进制串进行解码●实现压缩和解压缩功能2-2 数据结构----------在实现哈夫曼编码算法时,我们需要使用以下数据结构:●链表:用于存储字符出现的频率及对应的字符●堆:用于构建哈夫曼树●树:用于存储哈夫曼编码树●散列表或映射:用于存储字符的编码2-3 算法步骤----------1-统计字符的出现频率,并构建频率链表2-根据频率链表构建哈夫曼树3-字符的编码表4-对给定的字符串进行编码5-对给定的二进制串进行解码6-实现压缩和解压缩功能3-实验实现----------3-1 数据结构的设计----------在本实验中,我们将使用以下数据结构:●链表节点结构体:用于存储字符和频率●链表结构体:用于存储链表节点的头指针●堆节点结构体:用于存储字符和频率,并维护堆的结构●堆结构体:用于存储堆的根节点●树节点结构体:用于存储字符和编码,并维护哈夫曼树的结构●树结构体:用于存储哈夫曼树的根节点●散列表结构体:用于存储字符和对应的编码3-2 算法实现----------1-统计字符的出现频率并构建频率链表:遍历给定的字符串,统计字符的频率,并将字符频率按从小到大的顺序插入到频率链表中。
2-根据频率链表构建哈夫曼树:将频率链表的节点插入到堆中,并按照堆的定义调整堆的结构,直到堆中只有一个节点。
3-字符的编码表:遍历哈夫曼树,递归构造字符的编码表。
哈夫曼编码 实验报告
哈夫曼编码实验报告哈夫曼编码实验报告一、引言哈夫曼编码是一种用于数据压缩的算法,由大卫·哈夫曼于1952年提出。
它通过将出现频率高的字符用较短的编码表示,从而实现对数据的高效压缩。
本实验旨在通过实际操作和数据分析,深入了解哈夫曼编码的原理和应用。
二、实验目的1. 掌握哈夫曼编码的基本原理和算法;2. 实现哈夫曼编码的压缩和解压缩功能;3. 分析不同数据集上的压缩效果,并对结果进行评估。
三、实验过程1. 数据集准备本实验选取了三个不同的数据集,分别是一篇英文文章、一段中文文本和一段二进制数据。
这三个数据集具有不同的特点,可以用来评估哈夫曼编码在不同类型数据上的压缩效果。
2. 哈夫曼编码实现在实验中,我们使用了Python编程语言来实现哈夫曼编码的压缩和解压缩功能。
首先,我们需要统计数据集中各个字符的出现频率,并构建哈夫曼树。
然后,根据哈夫曼树生成每个字符的编码表,将原始数据转换为对应的编码。
最后,将编码后的数据存储为二进制文件,并记录编码表和原始数据的长度。
3. 压缩效果评估对于每个数据集,我们比较了原始数据和压缩后数据的大小差异,并计算了压缩比和压缩率。
压缩比是指压缩后数据的大小与原始数据大小的比值,压缩率是指压缩比乘以100%。
通过对比不同数据集上的压缩效果,我们可以评估哈夫曼编码在不同类型数据上的性能。
四、实验结果与分析1. 英文文章数据集对于一篇英文文章,经过哈夫曼编码压缩后,我们发现压缩比为0.6,即压缩后的数据只有原始数据的60%大小。
这说明哈夫曼编码在英文文本上具有较好的压缩效果。
原因在于英文文章中存在大量的重复字符,而哈夫曼编码能够利用字符的出现频率进行编码,从而减少数据的存储空间。
2. 中文文本数据集对于一段中文文本,我们发现哈夫曼编码的压缩效果不如在英文文章上的效果明显。
压缩比为0.8,即压缩后的数据只有原始数据的80%大小。
这是因为中文文本中的字符种类较多,并且出现频率相对均匀,导致哈夫曼编码的优势减弱。
哈弗曼编码数据结构实验报告
数据结构实验报告哈夫曼编码一、需求分析:哈夫曼编码可以进行求取最优二叉树,以及进行编码等实际问题,当利用哈夫曼树做前缀编码,有效的节约存储密码的时间。
二、概要设计:首先定义一个哈弗曼树结构体,哈夫曼编码数组之后,编写输入函数(包括存到文件的部分),哈弗曼构造函数(从文件中调用构造),求哈夫曼编码函数,输出函数(打印出哈夫曼编码)等。
三、详细设计:下为程序源代码:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<ctype.h>#define Maxsize 100typedef struct{char data;double weight;int parent;int lchild;int rchild;}HTNode;HTNode ht[Maxsize];typedef struct{char cd[Maxsize];int start;}HCode;HCode hcd[Maxsize];void Initialization(char str[], double w[], int n);void getn(char str[], double w[], int *n);void writehfmTree(int n);void Encoding(int n);void ReadhfmTree(void);void Decoding(int n);void TreePrint(int i);void Menu(char *ch);int getnumber(char *ch, int repeat);void Initialization(char str[], double w[], int n) //构造哈弗曼树{int i,k,lnode,rnode;double min1, min2;for(i=0; i<n; i++){ht[i].data = str[i];ht[i].weight = w[i];}for(i=0; i<2*n-1; i++)ht[i].lchild = ht[i].parent = ht[i].rchild = -1;for(i=n; i<2*n-1; i++){min1=min2=32767;lnode=rnode=-1;for(k=0; k<=i-1; k++){if(ht[k].parent == -1){if(ht[k].weight < min1){min2 = min1;rnode = lnode;min1 = ht[k].weight;lnode = k;}else if(ht[k].weight < min2){min2 = ht[k].weight;rnode = k;}}}ht[i].weight = ht[lnode].weight + ht[rnode].weight;ht[i].lchild = lnode;ht[i].rchild = rnode;ht[lnode].parent = i;ht[rnode].parent = i;}writehfmTree(n);}void getn(char str[], double w[], int *n){int i;FILE *fp;if((fp=fopen("ToBeTran", "w"))==NULL){printf("Can not open the file\n");exit(0);}printf("请输入字符集:");gets(str);gets(str);*n = strlen(str);for(i=0; i<*n; i++){printf("请输入%d个权值:", i+1);scanf("%lf",&w[i]);}for(i=0; i<*n; i++)fprintf(fp, "%c", str[i]);fclose(fp);}void writehfmTree(int n) //把哈弗曼树存入hrmTree文件中{int i;FILE *fp;if((fp=fopen("hfmTree","w"))==NULL){printf("Can not open the file\n");exit(0);}for(i=0; i<n; i++){fputc(ht[i].data, fp);fprintf(fp, "%.2f", ht[i].weight);}fprintf(fp,"\n");printf("存在文件hfmTree中的哈弗曼树形式为:\n");for(i=0; i<n; i++){putchar(ht[i].data);putchar('-');printf("%.2f ", ht[i].weight);}printf("\n文件hfmTree写入成功!\n");fclose(fp);}void Encoding(int n) //哈弗曼编码,并存于文件CodeFile中{int i, j, k, f, c;HCode hc;FILE *fp, *fp1;char text[Maxsize];ReadhfmTree();if((fp1=fopen("ToBeTran","r"))==NULL){printf("Can not open the file\n");exit(0);}fgets(text, Maxsize, fp1);printf("要进行编码的字符串是:\n");puts(text);fclose(fp1);if((fp=fopen("CodeFile","w"))==NULL){printf("Can not open the file\n");exit(0);}for(i=0; i<n; i++){hc.start = n;c=i;f=ht[i].parent;while(f!=-1){if(ht[f].lchild == c)hc.cd[hc.start--]='0';elsehc.cd[hc.start--]='1';c=f;f=ht[f].parent;}hc.start++;hcd[i]=hc;}i=0;while(text[i]!='\0'){j=0;while(text[i]!=ht[j].data){j++;}for(k=hcd[j].start; k<=n; k++){fprintf(fp, "%c", hcd[j].cd[k]);}fputc(' ', fp);i++;}printf("编码结果如下:\n");i=0;while(text[i]!='\0'){j=0;while(text[i]!=ht[j].data){j++;}for(k=hcd[j].start; k<=n; k++){printf("%c", hcd[j].cd[k]);}printf(" ");i++;}printf("\n文件CodeFile写入成功!\n");fclose(fp);}void ReadhfmTree(void) //从内存中读入哈弗曼树,或从文件hfmTree文件中读取哈弗曼树{FILE *fp;char str[Maxsize];double w[Maxsize];int i=0, n;if(sizeof(ht)!=0)printf("内存中已存有哈弗曼树!\n");else{printf("内存中哈弗曼树不存在,从文件中读取数据重新构造哈弗曼树!\n");if((fp=fopen("hfmTree","r"))==NULL){printf("Can not open the file\n");exit(0);}do{fscanf(fp, "%c", &str[i]);fscanf(fp, "%lf", &w[i]);i++;}while(str[i]!='\n');n = i-2;Initialization(str, w, n);fclose(fp);}}void Decoding(int n)//从文件CodeFile中读入哈弗曼树编码,进行译码,将译码结果存入TextFile文件中{int i=0, j=0, k=0, l=0, num;char *text[Maxsize], str[Maxsize][Maxsize];FILE *fp, *fp1;if((fp=fopen("CodeFile","r"))==NULL){printf("Can not open the file “CodeFile”\n");exit(0);}if((fp1=fopen("TextFile","w"))==NULL){printf("Can not open the file “TextFile”\n");exit(0);}for(i=0; i<Maxsize; i++)text[i] = str[i];i=0;while(fscanf(fp, "%s", text[i])==1)i++;num = i;for(i=0; i<num; i++){l=0;j=0;k=hcd[l].start;while(1){if(hcd[l].cd[k]!=text[i][j]){l++;j=0;k=hcd[l].start;}else{j++;k++;}if(j==(signed)strlen(text[i]) && k==n+1)break;}fprintf(fp1, "%c", ht[l].data);}printf("译码结果如下:\n");for(i=0; i<num; i++){l=0;j=0;k=hcd[l].start;while(1){if(hcd[l].cd[k]!=text[i][j]){l++;j=0;k=hcd[l].start;}else{j++;k++;}if(j==(signed)strlen(text[i]) && k==n+1)break;}printf("%c", ht[l].data);}printf("\n文件TextFile写入成功!\n");fclose(fp);fclose(fp1);}void Print(void)//将文件CodeFile以紧凑个数显示在终端上,每行50个代码。
2023年数据结构哈夫曼编码实验报告
数据构造试验汇报――试验五简朴哈夫曼编/译码旳设计与实现本试验旳目旳是通过对简朴哈夫曼编/译码系统旳设计与实现来纯熟掌握树型构造在实际问题中旳应用。
此试验可以作为综合试验,阶段性试验时可以选择其中旳几种功能来设计和实现。
一、【问题描述】运用哈夫曼编码进行通信可以大大提高信道运用率,缩短信息传播时间,减少传播成本。
不过,这规定在发送端通过一种编码系统看待传数据预先编码,在接受端将传来旳数据进行译码,此试验即设计这样旳一种简朴编/码系统。
系统应当具有如下旳几种功能:1、接受原始数据。
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文献nodedata.dat中。
2、编码。
运用已建好旳哈夫曼树(如不在内存,则从文献nodedata.dat中读入),对文献中旳正文进行编码,然后将成果存入文献code.dat中。
3、译码。
运用已建好旳哈夫曼树将文献code.dat中旳代码进行译码,成果存入文献textfile.dat中。
4、打印编码规则。
即字符与编码旳一一对应关系。
二、【数据构造设计】1、构造哈夫曼树时使用静态链表作为哈夫曼树旳存储。
在构造哈夫曼树时,设计一种构造体数组HuffNode保留哈夫曼树中各结点旳信息,根据二叉树旳性质可知,具有n个叶子结点旳哈夫曼树共有2n-1个结点,因此数组HuffNode 旳大小设置为2n-1,描述结点旳数据类型为:typedef struct{int weight;//结点权值int parent;int lchild;int rchild;char inf;}HNodeType;2、求哈夫曼编码时使用一维构造数组HuffCode作为哈夫曼编码信息旳存储。
求哈夫曼编码,实质上就是在已建立旳哈夫曼树中,从叶子结点开始,沿结点旳双亲链域回退到根结点,没回退一步,就走过了哈夫曼树旳一种分支,从而得到一位哈夫曼码值,由于一种字符旳哈夫曼编码是从根结点到对应叶子结点所通过旳途径上各分支所构成旳0、1序列,因此先得到旳分支代码为所求编码旳低位码,后得到旳分支代码位所求编码旳高位码,因此设计如下数据类型:#define MAXBIT 10typedef struct{int bit[MAXBIT];int start;}HcodeType;3、文献nodedata.dat、code.dat和textfile.dat。
哈夫曼编码实验报告
哈夫曼编码实验报告数据结构实验报告1.实验要求利用二叉树结构实现哈夫曼编/解码器。
基本要求:1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立哈夫曼树2、建立编码表(CreateTable):利用已经建好的哈夫曼树进行编码,并将每个字符的编码输出。
3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。
4、译码(Decoding):利用已经建好的哈夫曼树对编码后的字符串进行译码,并输出译码结果。
5、打印(Print):以直观的方式打印哈夫曼树(选作)计算输入的字符串编码前和编码后的长度,并进行分析,讨论哈夫曼编码的压缩效果。
并用I love data Structure, I love Computer。
I will try my best to study data Structure.进行测试。
2. 程序分析哈夫曼树结点的存储结构包括双亲域parent,左子树lchild,右子树rchild,还有字符word,权重weight,编码code对用户输入的信息进行统计,将每个字符作为哈夫曼树的叶子结点。
统计每个字符出现的次数作为叶子的权重,统计次数可以根据每个字符不同的ASCII码,根据叶子结点的权重建立一个哈夫曼树。
建立每个叶子的编码从根结点开始,规定通往左子树路径记为0,通往右子树路径记为1。
由于编码要求从根结点开始,所以需要前序遍历哈夫曼树,故编码过程是以前序遍历二叉树为基础的。
同时注意递归函数中能否直接对结点的编码域进行操作。
编码信息只要遍历字符串中每个字符,从哈夫曼树中找到相应的叶子结点,取得相应的编码。
最后再将所有找到的编码连接起来即可。
译码则是将编码串从左到右逐位判别,直到确定一个字符。
这就是哈夫曼树的逆过程。
遍历编码串,从哈夫曼树中找到相应的叶子结点,取得相应的字符再将找到的字符连接起来即可。
2.1 存储结构哈夫曼树结点存储结构2.2 关键算法分析1.统计字符频度自然语言描述:(1)取出字符串中的一个字符(2)遍历所有初始化的哈夫曼树结点(3)如果结点中有记录代表的字符且字符等于取出的字符,说明该字符的叶子存在,则将该结点的权值加1(4)如果所有结点记录的字符均没有与取出的字符一致,说明该字符的叶子不存在,则将结点的字符记为取出字符,并将权重设为1 (5)重复以上步骤,直至字符串中所有字符全部遍历伪代码描述:1. for(int i=0;i<length;i++)< p="">1.1 for (int j=0;j<length;j++)< p="">1.1.1if (WordStr[i]==HuffTree[j].word)//若字符已被统计,则增加权值即可1.1.1.1 权重++;1.1.1.2 break;1.1.2 else if(!HuffTree[j].word)//否则需要一个新结点储存这个字符1.1.2.1 HuffTree[j].word=WordStr[i];1.1.2.2 HuffTree[j].weight=1;1.1.2.3 叶子结点个数++;1.1.2.4 break;时间复杂度O(n2),空间复杂度S(0)2. 构造哈夫曼树自然语言描述:(1)选出权值最小的两个结点,其权值和作为其根结点的权值,最小的结点作为左子树,次小的作为右子树,不断将两棵子树合并为一棵树。
数据结构实验哈夫曼树及哈夫曼编码c语言
数据结构实验报告:哈夫曼树及哈夫曼编码一、实验目的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 对应的编码较长。
数据结构试验报告-哈弗曼编码
实验报告:哈弗曼编码班级:姓名:学号:一、需求分析:1.利用哈弗曼编码进行通信时可以大大提高信息利用率,缩短信息传输时间,降低传输成本;2.哈夫曼编码对终端“明文”文件中的正文进行编码,然后将结果存入“密文”中。
同时也可以将“密文”进行译码,提高了信息的安全性;3.输入输出的要求:要求在输入和输出端都有一个完整的编/译码系统,用户按照提示内容从键盘输入命令,系统根据用户输入的命令在保证界面友好的前提下输出用户所需要的信息,并按要求保存文件,以便保存备份信息;4.测试数据;1)令叶子节点的个数为4,权值集合为:w[]={5,7,11,6};2)令叶子节点的个数为8,权值集合为:w[]={7, 5, 2, 4, 14, 23, 3, 11};二、概要设计:1.定义哈弗曼编码数据结构类型:ADT Huffman{数据对象:D={ ai |ai 属于字符数集,i=1,2,3,4……n n>=0}数据关系:R1={<ai-1, ai >| ai-1, ai ∈D,ai-1< ai ,i=2……n}基本操作:void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n)初始条件:HT,HC,w,n等都存在操作结果:将w数组内的数都转化到HT内的哈夫曼树内,然后将哈夫曼树内的数据转化到HC这个代码中,全部转化成只有0和1这两个二进制数的一串译码。
void Select(HuffmanTree &HT, int s, int &s1, int &s2)初始条件:HT这个哈夫曼树存在操作结果:通过该个函数,将原来的哈夫曼树扩展成为有权值,双亲,左孩子,右孩子等四个值得哈夫曼树。
并用s1,s2两个字将双亲为0中权值最小的两个的下标返回到HuffmanCoding函数中,改变哈夫曼树。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告―― 实验五简单哈夫曼编/ 译码的设计与实现本实验的目的是通过对简单哈夫曼编/ 译码系统的设计与实现来熟练掌握树型结构在实际问题中的应用。
此实验可以作为综合实验,阶段性实验时可以选择其中的几个功能来设计和实现。
一、【问题描述】利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码,此实验即设计这样的一个简单编/ 码系统。
系统应该具有如下的几个功能:1、接收原始数据。
从终端读入字符集大小n ,以及n 个字符和n 个权值,建立哈夫曼树,并将它存于文件nodedata.dat 中。
2 、编码。
利用已建好的哈夫曼树(如不在内存,则从文件nodedata.dat 中读入),对文件中的正文进行编码,然后将结果存入文件code.dat 中。
3 、译码。
利用已建好的哈夫曼树将文件code.dat 中的代码进行译码,结果存入文件textfile.dat 中。
4、打印编码规则。
即字符与编码的一一对应关系。
二、【数据结构设计】1、构造哈夫曼树时使用静态链表作为哈夫曼树的存储。
在构造哈夫曼树时,设计一个结构体数组HuffNode 保存哈夫曼树中各结点的信息,根据二叉树的性质可知,具有n 个叶子结点的哈夫曼树共有2n-1 个结点,所以数组HuffNode 的大小设置为2n-1 ,描述结点的数据类型为:typedef struct{int weight;// 结点权值int parent;int lchild;int rchild;char inf;}HNodeType;2 、求哈夫曼编码时使用一维结构数组HuffCode 作为哈夫曼编码信息的存储。
求哈夫曼编码,实质上就是在已建立的哈夫曼树中,从叶子结点开始,沿结点的双亲链域回退到根结点,没回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值,由于一个字符的哈夫曼编码是从根结点到相应叶子结点所经过的路径上各分支所组成的0 、1 序列,因此先得到的分支代码为所求编码的低位码,后得到的分支代码位所求编码的高位码,所以设计如下数据类型:#define MAXBIT 10typedef structint bit[MAXBIT] ;int start ;}HcodeType ;3 、文件nodedata.dat 、code.dat 和textfile.dat 。
三、【功能(函数)设计】1、初始化功能模块。
此功能模块的功能为从键盘接收字符集大小n ,以及n 个字符和n个权值。
2 、建立哈夫曼树的功能模块。
此模块功能为使用 1 中得到的数据按照教材中的构造哈夫曼树的算法构造哈夫曼树,即将HuffNode 数组中的各个位置的各个域都添上相关的值,并将这个结构体数组存于文件hfmtree.dat 中。
3 、建立哈夫曼编码的功能模块。
此模块功能为从文件nodedata.dat 中读入相关的字符信息进行哈夫曼编码,然后将结果存入code.dat 中,同时将字符与0、 1 代码串的一一对应关系打印到屏幕上。
4、译码的功能模块。
此模块功能为接收需要译码的0、1 代码串,按照 3 中建立的编码规则将其翻译成字符集中字符所组成的字符串形式,存入文件textfile.dat ,同时将翻译的结果在屏幕上打印输出。
四、【编码实现】#include<iostream.h>#include<fstream.h>#include<string.h>#include<stdlib.h>#define MaxBit 10#define Maxvalue 100// 应该大于权重之和#define Maxleaf 100#define Maxnode Maxleaf*2-1typedef structint weight;{int parent;int lchild;int rchild;char inf;}HNodeType;struct HcodeType{int bit[MaxBit];int start;};void Creat_Haffmantree(int &n){HNodeType *HaffNode=new HNodeType[2*n-1]; int i,j;int m1,m2,x1,x2;for(i=0;i<2*n-1;i++){HaffNode[i].weight=0;HaffNode[i].lchild=-1;HaffNode[i].rchild=-1;HaffNode[i].inf='0';HaffNode[i].parent=-1;}for(i=0;i<n;i++){cout<<" 请输入字符"<<endl;cin>>HaffNode[i].inf;cout<<" 请输入该字符的权值"<<endl;cin>>HaffNode[i].weight;}for(i=0;i<n-1;i++)// 构造哈夫曼树{m1=m2=Maxvalue;x1=x2=0;for(j=0;j<n+i;j++)// 选取最小和次小{if(HaffNode[j].parent==-1&&HaffNode[j].weight<m1){m2=m1;x2=x1;m1=HaffNode[j].weight;x1=j;else{if(HaffNode[j].parent==-1&&HaffNode[j].weight<m2) {m2=HaffNode[j].weight;x2=j;}}}// 将找出的最小和次小合并,创造其父母结点HaffNode[x1].parent=n+i;HaffNode[x2].parent=n+i;HaffNode[n+i].weight=HaffNode[x1].weight+HaffNode[x2].weight;HaffNode[n+i].lchild=x1;HaffNode[n+i].rchild=x2;HaffNode[n+i].inf=NULL;}cout<<" 显示存储的哈弗曼树信息:"<<endl;cout<<" 权值左孩子右孩子双亲"<<endl;for(i=0;i<2*n-1;i++){cout<<HaffNode[i].weight<<" ";cout<<HaffNode[i].lchild<<" ";cout<<HaffNode[i].rchild<<" ";cout<<HaffNode[i].parent<<" ";cout<<HaffNode[i].inf<<endl;}// 写入文件fstream outfile1;outfile1.open("E:\\nodedata.dat",ios::out|ios::trunc|ios::binary);// 建立进行写入的文件if(!outfile1) // 没有创建成功则显示相应信息{cout<<"nodedata.dat 文件不能打开"<<endl;abort();}for(i=0;i<2*n-1;i++) // 将内存中从HaffNode[i] 地址开始的sizeof(HaffNode[i]) 的内容写入文件中outfile1.write((char*)&HaffNode[i],sizeof(HaffNode[i]));outfile1.close ();// 关闭文件delete []HaffNode;void HaffCode(int &n)// 哈夫曼编码{HNodeType *HaffNode=new HNodeType[Maxnode];HcodeType *HaffCode=new HcodeType[Maxleaf];HcodeType cd;int i,j,c,p;fstream in("E:\\nodedata.dat",ios::in|ios::binary);in.read((char*)HaffNode,(2*n-1)*sizeof(HNodeType));in.close();fstream outfile;outfile.open("E:\\codedata.dat",ios::out|ios::binary);// 入的文件建立进行写for(i=0;i<n;i++){cd.start=n-1;c=i;p=HaffNode[c].parent;while(p!=-1){if(HaffNode[p].lchild==c)cd.bit[cd.start]=0;elsecd.bit[cd.start]=1;cd.start--;c=p; p=HaffNode[c].parent;}for(j=cd.start+1;j<n;j++)HaffCode[i].bit[j]=cd.bit[j];HaffCode[i].start=cd.start;}for(i=0;i<n;i++){outfile<<HaffNode[i].inf;for(j=HaffCode[i].start+1;j<n;j++)outfile<<HaffCode[i].bit[j];}for(i=0;i<n;i++)cout<<" 字符信息-- 编码信息"<<endl; {cout<<HaffNode[i].inf<<"---";cout<<"code.dat 文件不能打开 !"<<endl;for(j=HaffCode[i].start+1;j<n;j++)cout<<HaffCode[i].bit[j];cout<<endl;}outfile.close ();cout<<" 请输入要编码的字符串 ,基本元素为( ";for(i=0;i<n;i++)cout<<HaffNode[i].inf<<",";cout<<")"<<endl;char inf[100];cin>>inf;int f=strlen(inf);fstream outfile1;outfile1.open("E:\\code.dat",ios::out|ios::binary);//文件if(!outfile1){abort();} else建立进行写入的{ cout<<endl;cout<<" 字符串编码后为:";for(int x=0;x<f;x++){for(i=0;i<n;i++){if(inf[x]==HaffNode[i].inf){for(j=HaffCode[i].start+1;j<n;j++){outfile1.write((char*)&HaffCode[i].bit[j],sizeof(HaffCode[i].bit[j]));cout<<HaffCode[i].bit[j];}}}}}cout<<endl;cout<<endl;outfile1.close();cout<<" 编译后的代码串已经存入code.dat 文件中!"<<endl;delete []HaffNode;delete []HaffCode;}void decode( int &n)// 解码{int i;HNodeType *HaffNode=new HNodeType[2*n-1];fstream infile1;infile1.open("E:\\nodedata.dat",ios::in|ios::binary);//读出哈夫曼树if(!infile1){cout<<"nodedata.dat 文件不能打开"<<endl;abort();}for(i=0;i<2*n-1;i++)infile1.read((char*)&HaffNode[i],sizeof(HNodeType));infile1.close();int tempcode[100];int num=0;for(i=0;i<100;i++)tempcode[i]=-1;HcodeType *Code=new HcodeType[n];fstream infile2;// 读编码infile2.open("E:\\code.dat",ios::in|ios::binary); while(!infile2.eof()){ infile2.read((char*)&tempcode[num],sizeof(tempcode[num])); num++; }infile2.close();num--;cout<<" 从文件中读出的编码为"<<endl;for(i=0;i<num;i++)cout<<tempcode[i];cout<<endl;int m=2*n-2;i=0;cout<<endl;cout<<" 译码后为:"<<endl;fstream outfile;outfile.open("E:\\textfile.txt",ios::out);if(!outfile)cout<<"textfile.txt 文件不能打开!"<<endl;abort();}while(i<num)// 小于字符串的长度{{while(HaffNode[m].lchild!=-1&&HaffNode[m].rchild!=-1) {if(tempcode[i]==0){m=HaffNode[m].lchild;i++;}else if(tempcode[i]==1){m=HaffNode[m].rchild;i++;}}cout<<HaffNode[m].inf;outfile<<HaffNode[m].inf;m=2*n-2;cout<<endl;outfile.close();cout<<" 译码后的结果已经存入textfile.txt 中!"<<endl; delete []HaffNode;}int main(){int n;cout<<"************* 欢迎进入编/ 译码系cout<<" 请选择(0~3):";cin>>ch1;while(!(ch1<=3&&ch1>=0)) // 输入不在0 到 4 之间无效统!*********************、'<<endl;int ch1;do{cout<<" 1.建树"<<endl;cout<<"2: 编码,并显示字符和对应的编码"<<endl;cout<<"3:译码"<<endl;cout<<" 0:退出"<<e ndl;cout<<" ********************************************************、'<<endl;{cout<<" 数据输入错误,请重新选择(0~4):";cin>>ch1;}switch(ch1){case 1:{cout<<"\t\t\t 请输入编码个数"<<endl;// 叶子结点个数cin>>n;Creat_Haffmantree(n);break;}case 2: HaffCode(n); break;case 3: decode(n); break;}}while(ch1!=0);return 0;五、【运行与测试】1、令叶子结点个数n 为4,权值集合为{1 ,3 , 5 ,7} ,字符集合为{A,B,C,D} ,并有如下对应关系,A――1、B――3 , C――5 , D――7,调用初始化功能模块可以正确接收这些数据。