实验三 哈夫曼树 实验报告
- 格式:docx
- 大小:128.88 KB
- 文档页数:12
数据结构哈夫曼树实验报告一、实验目的本次实验的主要目的是深入理解和掌握哈夫曼树的数据结构及其相关算法,通过实际编程实现哈夫曼编码和解码的过程,提高对数据结构的应用能力和编程技能。
二、实验环境本次实验使用的编程语言为 Python,开发工具为 PyCharm。
操作系统为 Windows 10。
三、实验原理哈夫曼树(Huffman Tree),又称最优二叉树,是一种带权路径长度最短的二叉树。
其基本思想是通过构建一棵二叉树,使得权值较大的节点离根节点较近,权值较小的节点离根节点较远,从而实现带权路径长度的最小化。
哈夫曼编码是一种基于哈夫曼树的变长编码方式。
对于给定的字符集及其出现的频率,通过构建哈夫曼树,可以为每个字符生成唯一的编码,使得编码后的字符串总长度最短。
在构建哈夫曼树的过程中,首先将每个字符及其出现的频率作为一个独立的节点,然后按照频率从小到大的顺序进行合并,每次合并两个频率最小的节点,生成一个新的节点,其频率为两个子节点频率之和。
重复这个过程,直到所有节点合并为一个根节点,最终得到的二叉树即为哈夫曼树。
四、实验步骤1、定义节点类```pythonclass Node:def __init__(self, char, freq, left=None, right=None):selfchar = charselffreq = freqselfleft = leftselfright = rightdef __lt__(self, other):return selffreq < otherfreq```这个节点类包含了字符、频率以及左右子节点的信息,并实现了小于比较方法,以便在构建哈夫曼树时进行节点的排序。
2、构建哈夫曼树```pythondef build_huffman_tree(freq_dict):nodes = Node(char, freq) for char, freq in freq_dictitems()while len(nodes) > 1:nodessort()left = nodespop(0)right = nodespop(0)merged_freq = leftfreq + rightfreqnew_node = Node(None, merged_freq, left, right)nodesappend(new_node)return nodes0```该函数根据字符频率字典创建节点列表,然后不断合并频率最小的两个节点,直到只剩下一个节点,即哈夫曼树的根节点。
数据结构实验报告实验名称:实验三哈夫曼树学生姓名:班级:班内序号:学号:日期:程序分析: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. 实验结果分析通过实验,验证了哈夫曼树和哈夫曼编码的正确性。
实验报告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. 理解并掌握哈夫曼树的创建过程;2. 理解并掌握哈夫曼编码的原理及其实现方法;3. 掌握哈夫曼树的基本操作,如求哈夫曼编码和哈夫曼解码等;4. 学习如何组织程序结构,运用C++语言实现哈夫曼编码和解码。
三、实验原理哈夫曼树的创建:哈夫曼树的创建过程就是一个不断合并权值最小的两个叶节点的过程。
具体步骤如下:1. 将所有节点加入一个无序的优先队列里;2. 不断地选出两个权值最小的节点,并将它们合并成为一个节点,其权值为这两个节点的权值之和;3. 将新的节点插入到队列中,并继续执行步骤2,直到队列中只剩下一棵树,这就是哈夫曼树。
哈夫曼编码:哈夫曼编码是一种无损压缩编码方式,它根据字符出现的频率来构建编码表,并通过编码表将字符转换成二进制位的字符串。
具体实现方法如下:1. 统计每个字符在文本中出现的频率,用一个数组记录下来;2. 根据字符出现的频率创建哈夫曼树;3. 从根节点开始遍历哈夫曼树,给左分支打上0的标记,给右分支打上1的标记。
遍历每个叶节点,将对应的字符及其对应的编码存储在一个映射表中;4. 遍历文本中的每个字符,查找其对应的编码表,并将编码字符串拼接起来,形成一个完整的编码字符串。
哈夫曼解码就是将编码字符串还原为原始文本的过程。
具体实现方法如下:1. 从根节点开始遍历哈夫曼树,按照编码字符串的位数依次访问左右分支。
如果遇到叶节点,就将对应的字符记录下来,并重新回到根节点继续遍历;2. 重复步骤1,直到编码字符串中的所有位数都被遍历完毕。
四、实验步骤1. 定义编码和解码的结构体以及相关变量;3. 遍历哈夫曼树,得到每个字符的哈夫曼编码,并将编码保存到映射表中;4. 将文本中的每个字符用其对应的哈夫曼编码替换掉,并将编码字符串写入到文件中;5. 使用哈夫曼编码重新构造文本,并将结果输出到文件中。
五、实验总结通过本次实验,我掌握了哈夫曼树的创建和哈夫曼编码的实现方法,也学会了如何用C++语言来组织程序结构,实现哈夫曼编码和解码。
一、实训目的本次实训旨在通过实际操作,让学生掌握哈夫曼树的基本概念、构建方法以及编码解码过程,加深对数据结构中树型结构在实际应用中的理解。
通过本次实训,学生能够: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)心得体会五、用户使用说明如上图所示, 依次输入组数、权值及全值所对应字符。
再根据用户自身需求输入需编译的文本及代码。
数据结构实验报告实验名称:实验三树学生姓名:班级:班内序号:学号:日期:2012年12月7号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、根据输入的字符串中每个字符出现的次数统计频度,对没有出现的字符一律不用编码。
2、 程序分析2.1存储结构(1)二叉树template <class T>class BiTree{public:BiTree(); //构造函数,其前序序列由键盘输入 ~BiTree(void); //析构函数BiNode<T>* Getroot(); //获得指向根结点的指针protected:BiNode<T> *root; //指向根结点的头指针};//声明类BiTree 及定义结构BiNodeData :二叉树是由一个根结点和两棵互不相交的左右子树构成。
二叉树中的结点具有相同数据类型及层次关系。
(2)静态三叉链表struct HNode //哈夫曼树的静态三叉链表 {unsigned int weight; //结点权值unsigned int parent; //双亲指针unsigned int Lchild; //左孩子指针unsigned int Rchild; //右孩子指针};示意图:(3) 编码表的节点结构 struct HCode //字符及其编码结构 {char data;char code[100];};示意图:2.2关键算法分析一:关键算法(一)初始化函数void Huffman::Init(int a[],int n)(1)算法自然语言1.创建一个长度为2*n -1的三叉链表2.将存储字符及其权值的链表中的字符逐个写入三叉链表的前n个结点的data域,并将对应结点的孩子域和双亲域赋为空3.从三叉链表的第n个结点开始,i=n3.1从存储字符及其权值的链表中取出两个权值最小的结点x,y,记录其下标x,y。
3.2将下标为x和y的哈夫曼树的结点的双亲设置为第i个结点3.3将下标为x的结点设置为i结点的左孩子,将下标为y的结点设置为i结点的右孩子,i结点的权值为x结点的权值加上y结点的权值,i结点的双亲设置为空4. 根据哈夫曼树创建编码表(2)源代码void Huffman::Init(int a[],int n) //创建哈夫曼树{ //二叉树只有度为和度为的结点时,总结点数为(n-1)个HTree=new HNode[2*n-1]; //根据权重数组a[1—>n]初始化哈夫曼树int i,x,y;for(i=0;i<n;i++) //n个叶子结点{HTree[i].weight=a[i];HTree[i].Lchild=-1;HTree[i].Rchild=-1;HTree[i].parent=-1;}for(int i=n;i<2*n-1;i++) //开始建哈夫曼树,从底层向顶层搭建{SelectMin(HTree,i,x,y); //从--(i-1)中选出两个权值最小的结点HTree[x].parent=i;HTree[y].parent=i; //左右孩子权值相加为父结点的权值HTree[i].weight=HTree[x].weight+HTree[y].weight;HTree[i].Lchild=x;HTree[i].Rchild=y;HTree[i].parent=-1;}}(3)时间复杂度在选取两个权值最小的结点的函数中要遍历链表,时间复杂度为O(n),故该函数的时间复杂度为O(n^2)(二)统计字符出现频度的代码(1)算法自然语言①用cin.getline()函数获取一段字符串。
同时设置一个权值数组weight,以及暂时统计和存放权值的数组s。
②用strlen()函数获取未编码时的字符串长度。
③从字符串的起始位置进行权值统计,即获得str[i]每个字符的ASⅡ编码,并在s[(int)str[i]]数组中进行+1统计,为字符出现一次。
④ i进行自加,统计下面字符出现的频度,在相应的数组元素中进行+1统计。
⑤继续循环,直到字符串结束。
(2)源代码(在main()函数中实现)int i,j=0,v;int s[200]={0};int weight[M]; //权值数组cout<<"请输入一段字符串,按回车键结束:"<<endl;cin.getline(str,1000,'\n'); //由用户输入一段字符串cout<<endl;Len1=strlen(str); //得到未编码时的字符串长度for(i=0;str[i]!='\0';i++) //统计每个字符的权值s[(int)str[i]]++; //(int)str[i]为每个字符的ASⅡ编码for(i=0;i<200;i++)if(s[i]!=0) //如果权值不为{c[j]=i; //ASⅡ编码为i的字符写入字符数组cweight[j]=s[i]; //权值s数组赋给权值weight数组 j++;}n=j; //叶子结点个数for(v=0;v<n;v++) //循环输出字符权值cout<<c[v]<<"的权值为:"<<weight[v]<<endl;(3)时间复杂度:若输入的字符串长度为n,则时间复杂度为O(n)(三)选择两个最小权值的函数(1)算法自然语言①先暂时将前两个叶子结点作为权值最小的两个结点i1,i2②从第三个叶子结点开始,每一个结点的权值与i1,i2进行比较,如果此结点权值比i1权值要小,则将i1结点赋给i2,此结点赋给i1。
③如果此结点权值比i2要小,此结点赋给i2。
④每进行一次循环,总结点个数-1.(两个结点进行权值合并)⑤继续执行循环,直到循环到根结点,循环结束。
(2)源代码void Huffman::SelectMin(HNode*hTree,int n,int &i1,int &i2){int i,j; //找一个比较的起始值for(i=0;i<n;i++) //找i1{if(hTree[i].parent==-1){i1=i;break;}}i++;for(;i<n;i++) //找i2{ //先让前两个叶子结点分别为i1,i2if(hTree[i].parent==-1){i2=i;break;}}if(hTree[i1].weight>hTree[i2].weight) //i1指向最小的{j=i2;i2=i1;i1=j;}i++;for(;i<n;i++) //开始找最小的两个{if(hTree[i].parent==-1&&hTree[i].weight<hTree[i1].weight){ //如果之后的叶子结点权值小于前两个,那么进行交换i2=i1; //把i1赋给i2i1=i;}else if(hTree[i].parent==-1&&hTree[i].weight<hTree[i2].weight){i2=i; //始终保证i2权值大于i1}}}(3)时间复杂度若输入的字符串长度为n,则时间复杂度为O(n)(四)创建编码表(1)算法自然语言1.生成一个编码表2.从终端结点开始,如果此结点是其父结点的左孩子,则标“0”;如果是其父结点的右孩子,则标“1”。
3.将父结点赋给孩子结点,并将新的孩子结点的父结点作为当前父结点,重复2操作。
4.继续循环,直到根结点,即不满足循环条件时,将编码表的最后一位置0.5.将编码字符逆置。
将编码串的最后一位置换成新编码串的第一位,倒数第二位置换成新编码串的第二位,直到置换完毕。
6.将新的编码串重新赋给编码表。
7.输出字符的哈夫曼编码。
8.循环将字符编码后的长度赋给Len3数组。
(2)源代码void Huffman::CreateTable(char data[],int n){HCodeTable=new HCode[n]; //生成编码表for(int i=0;i<n;i++){HCodeTable[i].data=data[i];int child=i;int parent=HTree[i].parent;int k=0; //从终端结点开始编码,代表每个编码串的长度while(parent!=-1){if(child==HTree[parent].Lchild)HCodeTable[i].code[k]='0'; //左孩子标“0”elseHCodeTable[i].code[k]='1'; //右孩子标“1”k++;child=parent; //向上追溯parent=HTree[child].parent;}HCodeTable[i].code[k]='\0'; //当编码到根结点时循环结束,编码串最后一位置表结束{ //将编码字符逆置char code[M];int u;for(u=0;u<k;u++)code[u]=HCodeTable[i].code[k-u-1];//上述编码串的最后一位变成新的编码表中编码串的第一位for(u=0;u<k;u++)HCodeTable[i].code[u]=code[u]; //将新的编码串重新赋给编码表cout<<c[i]<<"的哈夫曼编码为:";cout<<HCodeTable[i].code<<endl;Len3[i]=k; //每个字符编码后的长度}}}(3)时间复杂度若输入的字符串长度为n,则时间复杂度为O(n)。