哈夫曼树实验报告

合集下载

哈夫曼树实验报告

哈夫曼树实验报告

数据结构实验报告实验名称:实验三哈夫曼树学生姓名:班级:班内序号:学号:日期:程序分析:2.1 存储结构:二叉树2.2 程序流程:template <class T>class BiTree{public:BiTree(); //构造函数,其前序序列由键盘输入 ~BiTree(void); //析构函数BiNode<T>* Getroot(); //获得指向根结点的指针protected:BiNode<T> *root; //指向根结点的头指针};//声明类BiTree及定义结构BiNodeData:二叉树是由一个根结点和两棵互不相交的左右子树构成二叉树中的结点具有相同数据类型及层次关系哈夫曼树类的数据域,继承节点类型为int的二叉树class HuffmanTree:public BiTree<int>data:HCode* HCodeTable;//编码表int tSize; //编码表中的总字符数二叉树的节点结构template <class T>struct BiNode //二叉树的结点结构{T data; //记录数据T lchild; //左孩子T rchild; //右孩子T parent; //双亲};编码表的节点结构struct HCode{char data; //编码表中的字符char code[100]; //该字符对应的编码};待编码字符串由键盘输入,输入时用链表存储,链表节点为struct Node{char character; //输入的字符unsigned int count;//该字符的权值bool used; //建立树的时候该字符是否使用过Node* next; //保存下一个节点的地址};示意图:2.3 关键算法分析:1.初始化函数(void HuffmanTree::Init(string Input))算法伪代码:1.初始化链表的头结点2.获得输入字符串的第一个字符,并将其插入到链表尾部,n=1(n记录的是链表中字符的个数)3.从字符串第2个字符开始,逐个取出字符串中的字符3.1 将当前取出的字符与链表中已经存在的字符逐个比较,如果当前取出的字符与链表中已经存在的某个字符相同,则链表中该字符的权值加1。

哈夫曼树_实验报告

哈夫曼树_实验报告

一、实验目的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. 实验结果分析通过实验,验证了哈夫曼树和哈夫曼编码的正确性。

(完整word版)哈夫曼树实验报告

(完整word版)哈夫曼树实验报告

实验报告1、实验目的:(1)理解哈夫曼树的含义和性质。

(2)掌握哈夫曼树的存储结构以及描述方法。

(3)掌握哈夫曼树的生成方法。

(4)掌握哈夫曼编码的一般方法,并理解其在数据通讯中的应用.2、实验内容:哈夫曼树与哈弗曼编码、译码a。

问题描述:哈夫曼问题的提出可以参考教材P。

145。

利用哈弗曼编码进行通信可以大大提高通信利用率,缩短信息传输时间,降低传输成本。

但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码.b。

算法提示:参见教材P.147—148算法6.12、6。

13的描述.3、实验要求:建立哈夫曼树,实现编码,译码。

错误!.初始化(Initialization)。

从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。

○2。

编码(Encoding).利用已建好的哈夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran 中的正文进行编码,然后将结果存入文件CodeFile中。

○3.译码(Decoding ).利用已建好的哈夫曼树将文件CodeFile中的代码进行译码,结果存入文件T extFile 中。

错误!.输出代码文件(Print).将文件CodeFile以紧凑格式显示在终端上,每行50个代码。

同时将此字符形式的编码文件写入文件CodePrint中。

错误!。

输出哈夫曼树(TreePrinting).将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。

测试数据:设权值c= (a,b, c, d , e, f,g,h)w=(5,29,7,8,14,23,3,11),n=8。

按照字符‘0’或‘1’确定找左孩子或右孩子,则权值对应的编码为:5:0001,29:11,7:1110,8:111114:110,23:01,3:0000,11:001。

哈夫曼树编码实验报告

哈夫曼树编码实验报告

哈夫曼树编码实验报告哈夫曼树编码实验报告引言:哈夫曼树编码是一种常用的数据压缩算法,通过对数据进行编码和解码,可以有效地减小数据的存储空间。

本次实验旨在探究哈夫曼树编码的原理和应用,并通过实际案例验证其有效性。

一、哈夫曼树编码原理哈夫曼树编码是一种变长编码方式,根据字符出现的频率来确定不同字符的编码长度。

频率较高的字符编码较短,频率较低的字符编码较长,以达到最佳的数据压缩效果。

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. 接受原始数据从终端任意读入字母,求出其各自的权重值,建立哈夫曼树,并将它存于hfmtree.dat文件中。

2. 编码利用已建好的哈夫曼树,对文件中的正文进行编码,然后将结果存入codefile.dat中。

3. 译码利用已建好的哈夫曼树将文件codefile.dat中的代码进行译码,结果存入文件textfile.dat中。

4. 打印编码规则即字符与编码的一一对应关系。

5. 打印哈夫曼树将已存在内存中的哈夫曼树以直观的方式显示在终端上。

二、数据结构设计1. 构造哈夫曼树时使用静态量表作为哈夫曼树的存储。

在构造哈夫曼树时,设计一个结构体数组HuffNode保存哈夫曼树中各节点的信息,根据二叉树的性质可知,具有n个叶子节点的哈夫曼树共有2n-1个结点,所以数组HuffNode的大小设置为2n-1,描述节点的数据类型为:typedef struct{int weight; //结点权值int parent;int lchild;int rchild;}HNodeType;2. 求哈夫曼编码时使用一位结构数组HuffCode作为哈腹满编码信息的存储。

求哈夫曼编码,实质上就是在以建立的哈夫曼树中,从叶子结点开始,沿结点的双亲链域退到根结点,每退回一步,就走过了哈夫满树的一个分支,从而得到一位哈夫曼码值,由于一个字符的哈夫曼编码是从根结点到相应叶子结点所经过的路径上各分支所组成的0、1序列,因此先得到的分支代码为所求编码的低位码,后得到的分支代码为所求编码的高位码,所以设计如下数据类型:typedef struct{int bit[26];int start;}HCodeType;3. 文件hfmtree.dat、codefile.dat、和textfile.dat。

哈夫曼树编码实训报告

哈夫曼树编码实训报告

一、实训目的本次实训旨在通过实际操作,让学生掌握哈夫曼树的基本概念、构建方法以及编码解码过程,加深对数据结构中树型结构在实际应用中的理解。

通过本次实训,学生能够:1. 理解哈夫曼树的基本概念和构建原理;2. 掌握哈夫曼树的编码和解码方法;3. 熟悉Java编程语言在哈夫曼树编码中的应用;4. 提高数据压缩和传输效率的认识。

二、实训内容1. 哈夫曼树的构建(1)创建叶子节点:根据给定的字符及其权值,创建叶子节点,并设置节点信息。

(2)构建哈夫曼树:通过合并权值最小的两个节点,不断构建新的节点,直到所有节点合并为一棵树。

2. 哈夫曼编码(1)遍历哈夫曼树:从根节点开始,按照左子树为0、右子树为1的规则,记录每个叶子节点的路径。

(2)生成编码:将遍历过程中记录的路径转换为二进制编码,即为哈夫曼编码。

3. 哈夫曼解码(1)读取编码:将编码字符串按照二进制位读取。

(2)遍历哈夫曼树:从根节点开始,根据读取的二进制位,在哈夫曼树中寻找对应的节点。

(3)输出解码结果:当找到叶子节点时,输出对应的字符,并继续读取编码字符串。

三、实训过程1. 准备工作(1)创建一个Java项目,命名为“HuffmanCoding”。

(2)在项目中创建以下三个类:- HuffmanNode:用于存储哈夫曼树的节点信息;- HuffmanTree:用于构建哈夫曼树、生成编码和解码;- Main:用于实现主函数,接收用户输入并调用HuffmanTree类进行编码和解码。

2. 编写代码(1)HuffmanNode类:```javapublic class HuffmanNode {private char data;private int weight;private HuffmanNode left;private HuffmanNode right;public HuffmanNode(char data, int weight) {this.data = data;this.weight = weight;}}```(2)HuffmanTree类:```javaimport java.util.PriorityQueue;public class HuffmanTree {private HuffmanNode root;public HuffmanNode buildHuffmanTree(char[] data, int[] weight) {// 创建优先队列,用于存储叶子节点PriorityQueue<HuffmanNode> queue = new PriorityQueue<>();for (int i = 0; i < data.length; i++) {HuffmanNode node = new HuffmanNode(data[i], weight[i]);queue.offer(node);}// 构建哈夫曼树while (queue.size() > 1) {HuffmanNode left = queue.poll();HuffmanNode right = queue.poll();HuffmanNode parent = new HuffmanNode('\0', left.weight + right.weight);parent.left = left;parent.right = right;queue.offer(parent);}root = queue.poll();return root;}public String generateCode(HuffmanNode node, String code) {if (node == null) {return "";}if (node.left == null && node.right == null) {return code;}generateCode(node.left, code + "0");generateCode(node.right, code + "1");return code;}public String decode(String code) {StringBuilder result = new StringBuilder();HuffmanNode node = root;for (int i = 0; i < code.length(); i++) {if (code.charAt(i) == '0') {node = node.left;} else {node = node.right;}if (node.left == null && node.right == null) { result.append(node.data);node = root;}}return result.toString();}}```(3)Main类:```javaimport java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请输入字符串:");String input = scanner.nextLine();System.out.println("请输入字符及其权值(例如:a 2 b 3 c 5):"); String[] dataWeight = scanner.nextLine().split(" ");char[] data = new char[dataWeight.length / 2];int[] weight = new int[dataWeight.length / 2];for (int i = 0; i < dataWeight.length; i += 2) {data[i / 2] = dataWeight[i].charAt(0);weight[i / 2] = Integer.parseInt(dataWeight[i + 1]);}HuffmanTree huffmanTree = new HuffmanTree();HuffmanNode root = huffmanTree.buildHuffmanTree(data, weight); String code = huffmanTree.generateCode(root, "");System.out.println("编码结果:" + code);String decoded = huffmanTree.decode(code);System.out.println("解码结果:" + decoded);scanner.close();}}```3. 运行程序(1)编译并运行Main类,输入字符串和字符及其权值。

哈夫曼树 实验报告

哈夫曼树 实验报告

哈夫曼树实验报告哈夫曼树实验报告引言:哈夫曼树是一种经典的数据结构,广泛应用于数据压缩、编码和解码等领域。

本次实验旨在通过构建哈夫曼树,探索其原理和应用。

一、哈夫曼树的定义和构建方法哈夫曼树是一种特殊的二叉树,其叶子节点对应于待编码的字符,而非叶子节点则是字符的编码。

构建哈夫曼树的方法是通过贪心算法,即每次选择权值最小的两个节点合并,直到构建出完整的哈夫曼树。

二、哈夫曼编码的原理和实现哈夫曼编码是一种可变长度编码,即不同字符的编码长度不同。

其原理是通过构建哈夫曼树来确定字符的编码,使得频率较高的字符编码较短,频率较低的字符编码较长。

这样可以有效地减少编码的长度,从而实现数据的压缩。

三、实验过程和结果在本次实验中,我们选择了一段文本作为输入数据,通过统计每个字符的频率,构建了对应的哈夫曼树。

然后,根据哈夫曼树生成了字符的编码表,并将原始数据进行了编码。

最后,我们通过对编码后的数据进行解码,验证了哈夫曼编码的正确性。

实验结果显示,通过哈夫曼编码后,原始数据的长度明显减少,达到了较好的压缩效果。

同时,解码后的数据与原始数据完全一致,证明了哈夫曼编码的可靠性和正确性。

四、哈夫曼树的应用哈夫曼树在实际应用中有着广泛的用途。

其中,最典型的应用之一是数据压缩。

通过使用哈夫曼编码,可以将大量的数据压缩为较小的存储空间,从而节省了存储资源。

此外,哈夫曼树还被广泛应用于网络传输、图像处理等领域,提高了数据传输的效率和图像的质量。

五、对哈夫曼树的思考哈夫曼树作为一种经典的数据结构,其优势在于有效地减少了数据的冗余和存储空间的占用。

然而,随着技术的不断发展,现代的数据压缩算法已经不再局限于哈夫曼编码,而是采用了更为复杂和高效的算法。

因此,我们需要在实际应用中综合考虑各种因素,选择合适的压缩算法。

六、总结通过本次实验,我们深入了解了哈夫曼树的原理和应用。

哈夫曼编码作为一种重要的数据压缩算法,具有广泛的应用前景。

在实际应用中,我们需要根据具体情况选择合适的压缩算法,以达到最佳的压缩效果和性能。

哈夫曼树实验报告

哈夫曼树实验报告

哈夫曼树实验报告一、需求分析(1)输入输出形式输入数组的组数n: 整形变量组数(回车)请依次输入n组权值与字符, 中间用空格隔开。

如“2 a”:按右提示格式输入(回车)请输入待编译文本: 随机输入字符(回车)输出: 编译出的代码请输入待编译代码: 随机输入一串代码(回车)(2)输出: 编译出的代码(3)程序功能1. 用C语言实现二叉树的说明2. 输入n个权值, 并生成n个二叉树3. 对n个二叉树逐步生成Huffman树4. 对Huffman树的每个叶子结点生成编码5.用哈夫曼树编码。

6.解码哈夫曼编码。

(4)测试用例设计Example1: 输入325 a15 b60 cabbacc010*******输出010*******abbaccExample2: 输入510 a20 b30 c20 d10 eababcde10000100001101101输出10000100001101101ababcde二、概要设计1.根据给定的n个权值(w1, w2, …, wn)构成n棵二叉树的集合F={T1, T2, …, Tn}, 其中每棵二叉树Ti中只有一个带树为Ti的根结点在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树, 且置其根结点的权值为其左右子树权值之和3.在F中删除这两棵树, 同时将新得到的二叉树加入F中4.重复2, 3, 直到F只含一棵树为止三、 5.将给定的字符串通过程序编码成哈夫曼编码, 并打印结果在屏幕上。

四、 6.翻译给定的哈夫曼编码变成可读字符串, 并将结果打印在屏幕上。

五、详细设计四、调试分析(1)编译代码、运行代码所遇到的问题及其解决办法问题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. 熟悉哈夫曼编码和译码的实现过程。

4. 分析哈夫曼编码在数据压缩中的应用效果。

二、实验原理哈夫曼编码是一种基于字符频率的编码方法,它利用字符出现的频率来构造一棵最优二叉树(哈夫曼树),并根据该树生成字符的编码。

在哈夫曼树中,频率越高的字符对应的编码越短,频率越低的字符对应的编码越长。

这样,对于出现频率较高的字符,编码后的数据长度更短,从而实现数据压缩。

三、实验内容1. 构建哈夫曼树:- 统计待编码数据中每个字符出现的频率。

- 根据字符频率构建哈夫曼树,其中频率高的字符作为叶子节点,频率低的字符作为内部节点。

- 重复上述步骤,直到树中只剩下一个节点,即为哈夫曼树的根节点。

2. 生成哈夫曼编码:- 从哈夫曼树的根节点开始,对每个节点进行遍历,根据遍历方向(左子树为0,右子树为1)为字符分配编码。

- 将生成的编码存储在编码表中。

3. 编码和译码:- 使用生成的编码表对原始数据进行编码,将编码后的数据存储在文件中。

- 从文件中读取编码后的数据,根据编码表进行译码,恢复原始数据。

四、实验步骤1. 编写代码实现哈夫曼树的构建:- 定义节点结构体,包含字符、频率、左子树、右子树等属性。

- 实现构建哈夫曼树的核心算法,包括节点合并、插入等操作。

2. 实现编码和译码功能:- 根据哈夫曼树生成编码表。

- 编写编码函数,根据编码表对数据进行编码。

- 编写译码函数,根据编码表对数据进行译码。

3. 测试实验效果:- 选择一段文本数据,使用实验代码进行编码和译码。

- 比较编码前后数据的长度,分析哈夫曼编码的压缩效果。

五、实验结果与分析1. 哈夫曼树构建:- 成功构建了哈夫曼树,树中节点按照字符频率从高到低排列。

2. 哈夫曼编码:- 成功生成编码表,字符与编码的对应关系符合哈夫曼编码原理。

3. 编码与译码:- 成功实现编码和译码功能,编码后的数据长度明显缩短,译码结果与原始数据完全一致。

哈弗曼树实验报告(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()`,用于生成哈弗曼编码。

数据结构实验报告(哈夫曼树)

数据结构实验报告(哈夫曼树)

数据结构实验报告实验题目:Huffman编码与解码姓名:学号:院系:实验名称:Huffman编码与解码实验问题描述:本实验需要以菜单形式完成以下功能:1.输入电文串2.统计电文串中各个字符及其出现的次数3.构造哈弗曼树4.进行哈弗曼编码5.将电文翻译成比特流并打印出来6.将比特流还原成电文数据结构的描述:逻辑结构:本实验可用二叉树实现,其逻辑结构为一对二的形式,即一个结点对应两个结点。

在实验过程中我们也应用到了栈的概念。

存储结构:使用结构体来对数据进行存储:typedef struct{int weight;int parent,lc,rc;}HTNode,*HuffmanTree;typedef struct LNode{char *elem;int stacksize;int top;}SqStack;在main函数里面定义一个哈弗曼树并实现上述各种功能。

程序结构的描述:本次实验一共构造了10个函数:1.void HuffTree(HuffmanTree &HT,int n[],int mun);此函数根据给定的mun个权值构建哈弗曼树,n[]用于存放num个权值。

2.void Select(HuffmanTree &HT,int n,int i,int &s1,int &s2);此函数用于在HT[1,i-1]中选择parent为0且weight为最小的两个结点,其下标分别为s1,s2.3.void HuffmanCoding(HuffmanTree HT,char **&HC,int n);此函数从哈弗曼树HT上求得n 个叶子结点的哈弗曼编码并存入数组HC中。

4.void Coding(HuffmanTree HT,char **HC,int root,SqStack &S);此函数用于哈弗曼编码,先序遍历哈弗曼树HT,求得每个叶子结点的编码字符串,存入数组HC,S为一个顺序栈,用来记录遍历路径,root是哈弗曼数组HT中根结点的位置下标。

哈夫曼树实验报告(上传)

哈夫曼树实验报告(上传)

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、虽然最终顺利的编完了程序,但是总的来说哈夫曼树还是很不容易的。

数据结构实验哈夫曼树及哈夫曼编码c语言

数据结构实验哈夫曼树及哈夫曼编码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 对应的编码较长。

树和哈夫曼树实验报告

树和哈夫曼树实验报告

哈夫曼树实验报告2011.4.22实验题目: Huffman编码和译码。

实验目的:1、练习树和哈夫曼树的有关操作, 和各个算法程序。

2.理解哈夫曼树的编码和译码实验内容:抽象数据类型:ADT Huffmantree{数据对象: D={带有各自实数W(D)的数据元素}数据关系: (1) D=NULL 则huffman tree 不存在//判断huffman树是否存在(2) D≠NULL R={H}.H为如下二元关系://如果存在, 假设R为其元素名称, H为里边所有元素①D中存在唯一根数据元素root,这个元素无前驱。

//如果只有一个元素, 则为根元素②D-{root} ≠NULL.则存在D-{root} ={D1, Dr}.且D1∧Dr=NULL//如果除了根元素还有别的元素, 那么会有D1和Dr两部分, 并且两者的交集为空, 也就是两者是独立的。

③若D1 ≠NULL , 则D1 中存在唯一元素xr,<root, xr>∈H//如果D1部位空集, 则会有一个元素xr, 且存在Dr上关系Hr ∈H,H= {<root ,x1>,< root, xr>,H1,Hr};④符合①②③的R的组合中, 存在一个组合R’使D中所有结点到root长与其权值W(Di)相乘的和最小, 此时的<D/R>集合称为huffman tree.基本操作:void select(HTNode HT[],int m,int *s1,int *s2)//比较得到权最小的两棵树。

用指针指向所在位置。

*void print1(char *HC[])//将哈弗曼编码逐个打印出来void print2(HTNode HT[])//将哈夫曼树前后的结构打印出来void CreatHuffmanTree(HTNode HT[],lettervalue w[])//建立哈夫曼树void HuffmanTreeCoding(HTNode HT[],char *HC[])//从树根出发, 对哈夫曼树做一次先序遍历, 在遍历过程中利用一个字符//的顺序栈S记下遍历路程, 向左转时0入栈, 向右转时1入栈。

哈夫曼实验报告总结

哈夫曼实验报告总结

哈夫曼实验报告总结哈夫曼编码是一种用于数据压缩的有效算法,它能够将出现频率较高的字符用较短的编码表示,而将出现频率较低的字符用较长的编码表示,从而实现数据的压缩。

本次实验的目的是通过实现哈夫曼编码算法,深入理解哈夫曼编码的原理和应用,并通过实验证明其压缩效果。

在实验中,我们首先需要计算每个字符在给定文本中的出现频率。

通过统计文本中的字符频率,我们可以构建出一个字符频率表,其中每个字符和其对应的频率成对出现。

接下来,根据字符频率表,我们需要构建哈夫曼树。

哈夫曼树是一种特殊的二叉树,它的叶子节点对应于字符,而非叶子节点对应于字符的编码。

构建哈夫曼树的过程是通过将频率较小的字符不断相加作为新的频率节点,直到最终构建出完整的哈夫曼树。

构建哈夫曼树的过程是一个递归的过程,可以通过优先队列或最小堆来实现。

构建完哈夫曼树后,我们可以根据哈夫曼树为每个字符生成对应的编码。

在哈夫曼树中,从根节点到叶子节点的路径表示字符的编码,路径上的左-右方向分别表示0和1。

生成编码的过程是通过遍历哈夫曼树的路径,并记录经过的方向来实现的。

为了更高效地生成编码,可以使用哈希表或者数组来存储每个字符对应的编码。

实验中,我们将生成的哈夫曼编码应用于数据的压缩。

通过将文本中的每个字符替换为其对应的哈夫曼编码,并将生成的编码串连接起来,可以实现对数据的压缩。

压缩效果取决于字符的频率分布情况,频率更高的字符会得到较短的编码,而频率较低的字符会得到较长的编码。

在本次实验中,我们通过分别计算原始文本和压缩后文本的字节数,计算了压缩率。

压缩率的计算公式为:压缩率 = (1 - 压缩后字节数 / 原始字节数) * 100%。

通过实验数据的对比,我们可以发现,哈夫曼编码能够有效地减小数据的存储空间,实现较高的压缩率。

通过本次实验,我深入学习了哈夫曼编码的原理和实现方法。

哈夫曼编码是一种非常有效的数据压缩算法,广泛应用于各类数据压缩工具和通信传输中。

哈夫曼树实验报告

哈夫曼树实验报告

一、实验目的1. 理解哈夫曼树的基本概念和构造方法。

2. 掌握哈夫曼编码的原理和实现过程。

3. 通过实验加深对数据结构中树型结构应用的理解。

二、实验原理哈夫曼树(Huffman Tree)是一种带权重的二叉树,用于实现哈夫曼编码。

其基本思想是:将字符按照在数据集中出现的频率进行排序,然后选取两个最小频率的字符合并成一个新节点,其频率为两个字符频率之和,重复此过程,直到只剩下一个节点,即为哈夫曼树的根节点。

哈夫曼编码是一种基于哈夫曼树的编码方法,其原理是将每个字符映射到一个唯一的二进制序列,序列的长度与字符在数据集中出现的频率成反比。

频率越高,编码的长度越短,从而提高信息传输的效率。

三、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019四、实验步骤1. 初始化(1)从数据文件中读取字符及其频率。

(2)构建一个优先队列(最小堆),将字符和频率存储在队列中。

2. 构建哈夫曼树(1)从优先队列中取出两个频率最小的节点,合并成一个新节点,其频率为两个节点频率之和。

(2)将新节点插入优先队列中。

(3)重复步骤(1)和(2),直到优先队列中只剩下一个节点,即为哈夫曼树的根节点。

3. 哈夫曼编码(1)遍历哈夫曼树,从根节点到叶子节点的路径上,左子树表示0,右子树表示1。

(2)将每个叶子节点的字符和对应的编码存储在哈夫曼编码表中。

4. 编码(1)读取待编码的文本。

(2)根据哈夫曼编码表,将文本中的每个字符映射到对应的编码。

(3)将编码序列写入文件。

5. 译码(1)读取编码文件。

(2)从哈夫曼树的根节点开始,根据编码序列的每一位,判断是左子树还是右子树。

(3)当到达叶子节点时,输出对应的字符。

(4)重复步骤(2)和(3),直到编码序列结束。

五、实验结果与分析1. 实验结果(1)成功构建了哈夫曼树,并生成了哈夫曼编码表。

(2)对给定的文本进行了编码和译码,验证了编码的正确性。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构实验报告实验名称:实验三哈夫曼树学生姓名:班级:班内序号:学号:日期:程序分析:2.1 存储结构:二叉树2.2 程序流程:template <class T>class BiTree{public:BiTree(); //构造函数,其前序序列由键盘输入 ~BiTree(void); //析构函数BiNode<T>* Getroot(); //获得指向根结点的指针protected:BiNode<T> *root; //指向根结点的头指针};//声明类BiTree及定义结构BiNodeData:二叉树是由一个根结点和两棵互不相交的左右子树构成二叉树中的结点具有相同数据类型及层次关系哈夫曼树类的数据域,继承节点类型为int的二叉树class HuffmanTree:public BiTree<int>data:HCode* HCodeTable;//编码表int tSize; //编码表中的总字符数二叉树的节点结构template <class T>struct BiNode //二叉树的结点结构{T data; //记录数据T lchild; //左孩子T rchild; //右孩子T parent; //双亲};编码表的节点结构struct HCode{char data; //编码表中的字符char code[100]; //该字符对应的编码};待编码字符串由键盘输入,输入时用链表存储,链表节点为struct Node{char character; //输入的字符unsigned int count;//该字符的权值bool used; //建立树的时候该字符是否使用过Node* next; //保存下一个节点的地址};示意图:2.3 关键算法分析:1.初始化函数(void HuffmanTree::Init(string Input))算法伪代码:1.初始化链表的头结点2.获得输入字符串的第一个字符,并将其插入到链表尾部,n=1(n记录的是链表中字符的个数)3.从字符串第2个字符开始,逐个取出字符串中的字符3.1 将当前取出的字符与链表中已经存在的字符逐个比较,如果当前取出的字符与链表中已经存在的某个字符相同,则链表中该字符的权值加1。

3.2 如果当前取出的字符与链表中已经存在的字符都不相同,则将其加入到链表尾部,同时n++4.tSize=n(tSize记录链表中字符总数,即哈夫曼树中叶子节点总数)5.创建哈夫曼树6.销毁链表源代码:void HuffmanTree::Init(string Input){Node *front=new Node; //初始化链表的头结点if(!front)throw exception("堆空间用尽");front->next=NULL;front->character=NULL;front->count=0;Node *pfront=front;char ch=Input[0]; //获得第一个字符Node* New1=new Node;if(!New1)throw exception("堆空间用尽");New1->character=ch; //将第一个字符插入链表New1->count=1;New1->next=pfront->next;pfront->next=New1;bool replace=0; //判断在已经写入链表的字符中是否有与当前读出的字符相同的字符int n=1; //统计链表中字符个数for(int i=1;i<Input.length();i++){ch=Input[i]; //获得第i个字符do{pfront=pfront->next;if((int)pfront->character == (int)ch) //如果在链表中有与当前字符相同的字符,该字符权值加1{pfront->count++;replace=1;break;}}while(pfront->next);if(!replace) //如果在链表中没找到与当前字符相同的字符,则将该字符作为新成员插入链表{Node* New=new Node;if(!New)throw exception("堆空间用尽");New->character=ch;New->count=1;New->next=pfront->next;pfront->next=New;n++;}pfront=front; //重置pfront和replace变量为默认值replace=0;}tSize=n; //tSize记录的是编码表中字符个数CreateHTree(front,n); //创建哈夫曼树pfront=front;while(pfront) //销毁整个链表{front=pfront;pfront=pfront->next;delete front;}时间复杂度:若输入的字符串长度为n,则时间复杂度为O(n)2.创建哈夫曼树(void HuffmanTree::CreateCodeTable(Node *p))算法伪代码:1.创建一个长度为2*tSize-1的三叉链表2.将存储字符及其权值的链表中的字符逐个写入三叉链表的前tSize个结点的data域,并将对应结点的孩子域和双亲域赋为空3.从三叉链表的第tSize个结点开始,i=tSize3.1从存储字符及其权值的链表中取出两个权值最小的结点x,y,记录其下标x,y。

3.2将下标为x和y的哈夫曼树的结点的双亲设置为第i个结点3.3将下标为x的结点设置为i结点的左孩子,将下标为y的结点设置为i结点的右孩子,i结点的权值为x结点的权值加上y结点的权值,i结点的双亲设置为空4. 根据哈夫曼树创建编码表源代码:void HuffmanTree::CreateHTree(Node *p,int n){root= new BiNode<int>[2*n-1]; //初始化哈夫曼树Node *front=p->next;if(n==0)throw exception("没有输入字符");for(int i=0;i<n;i++) //将n个字符的权值存储在哈夫曼树数组的前n位{root[i].data=front->count;root[i].lchild=-1;root[i].rchild=-1;root[i].parent=-1;front=front->next;}front=p;int New1,New2;for(i=n;i<2*n-1;i++){SelectMin(New1,New2,0,i); //从0~i中选出两个权值最小的结点root[New1].parent=root[New2].parent=i; //用两个权值最小的结点生成新结点,新节点为其双亲root[i].data=root[New1].data+root[New2].data;//新结点的权值为其孩子的权值的和root[i].lchild=New1;root[i].rchild=New2;root[i].parent=-1;}CreateCodeTable(p); //创建编码表}时间复杂度:在选取两个权值最小的结点的函数中要遍历链表,时间复杂度为O(n),故该函数的时间复杂度为O(n^2)3.创建编码表(void HuffmanTree::CreateCodeTable(Node *p))算法伪代码:1.初始化编码表2.初始化一个指针,从链表的头结点开始,遍历整个链表2.1 将链表中指针当前所指的结点包含的字符写入编码表中2.2 得到该结点对应的哈夫曼树的叶子结点及其双亲2.3 如果哈夫曼树只有一个叶子结点,将其字符对应编码设置为02.4 如果不止一个叶子结点,从当前叶子结点开始判断2.4.1 如果当前叶子结点是其双亲的左孩子,则其对应的编码为0,否则为12.4.2 child指针指向叶子结点的双亲,parent指针指向child指针的双亲,重复2.4.1的操作2.5 将已完成的编码倒序2.6 取得链表中的下一个字符3.输出编码表源代码:void HuffmanTree::CreateCodeTable(Node *p){HCodeTable=new HCode[tSize]; //初始化编码表Node *front=p->next;for(int i=0;i<tSize;i++){HCodeTable[i].data=front->character; //将第i个字符写入编码表int child=i; //得到第i个字符对应的叶子节点int parent=root[i].parent; //得到第i个字符对应的叶子节点的双亲int k=0;if(tSize==1) //如果文本中只有一种字符,它的编码为0 {HCodeTable[i].code[k]='0';k++;}while(parent!=-1) //从第i个字符对应的叶子节点开始,寻找它到根结点的路径{if(child==root[parent].lchild) //如果当前结点为双亲的左孩子,则编码为0,否则编码为1HCodeTable[i].code[k]='0';elseHCodeTable[i].code[k]='1';k++;child=parent;parent=root[child].parent;}HCodeTable[i].code[k]='\0';Reverse(HCodeTable[i].code); //将编码逆置front=front->next; //得到下一个字符}cout<<"编码表为:"<<endl;for(i=0;i<tSize;i++) //输出编码表{cout<<HCodeTable[i].data<<' '<<HCodeTable[i].code<<endl;}}时间复杂度:需要遍历哈夫曼树获取编码,时间复杂度为O(n^2)4.选择两个最小权值的函数算法伪代码:1.从下标为begin的结点开始,寻找第一个没用过的结点2.遍历哈夫曼树中从下标为begin到下标为end的结点序列,寻找没用过的同时权值又是最小的结点。

相关文档
最新文档