Java Huffman 编码2025年03月17日 | 阅读 9 分钟 哈夫曼编码算法由 David A. Huffman 于 1950 年提出。它是一种 无损数据压缩 机制。它也称为 数据压缩编码。 它被广泛用于图像(JPEG 或 JPG)压缩。在本节中,我们将讨论 哈夫曼编码 和 解码, 并用 Java 程序实现其算法。 我们知道每个字符都是由 0 和 1 组成的序列,并使用 8 位存储。该机制称为 定长编码,因为每个字符都使用相同数量的固定位数存储。 这时,会有一个问题出现:是否有可能减少存储字符所需的空间量? 是的, 使用 变长编码 是可能的。在这种机制中,我们利用一些比其他字符出现频率更高的字符。在这种编码技术中,我们可以通过减少位数来表示相同文本或字符串。 哈夫曼编码哈夫曼编码实现以下步骤。
哈夫曼编码遵循 前缀规则,该规则可防止在解码时产生歧义。该规则还确保分配给字符的编码不会被视为分配给任何其他字符的编码的前缀。 哈夫曼编码涉及以下两个主要步骤:
让我们简要介绍上述两个步骤。 哈夫曼树步骤 1: 对于每个字符节点,创建一个叶节点。字符的叶节点包含该字符的频率。 步骤 2: 根据频率对所有节点进行排序。 步骤 3: 可能存在两个节点频率相同的情况。在这种情况下,请执行以下操作:
步骤 4: 重复步骤 2 和 3,直到所有节点形成一棵单一的树。这样,我们就得到了一棵哈夫曼树。 哈夫曼编码示例假设我们要编码字符串 abracadabra。 确定以下内容:
(i) 所有字符的哈夫曼编码为了确定每个字符的编码,我们首先构建 哈夫曼树。 步骤 1: 将字符与其频率配对。 (a, 5), (b, 2), (c, 1), (d, 1), (r, 2) 步骤 2: 根据频率对配对进行排序,我们得到 (c, 1), (d, 1), (b, 2) (r, 2), (a, 5) 步骤 3: 选择前两个字符并将它们组合在一个父节点下。 ![]() 我们观察到父节点没有频率,所以我们必须给它分配频率。父节点的频率将是其左右子节点的频率之和,即 1+1=2。 ![]() 步骤 4: 重复步骤 2 和 3,直到我们得到一棵单一的树。 我们观察到配对已经按排序(根据步骤 2)顺序排列。再次选择前两个配对并将它们组合起来。 ![]() 我们观察到父节点没有频率,所以我们必须给它分配频率。父节点的频率将是其左右子节点的频率之和,即 2+2=4。 ![]() 再次,我们检查配对是否按排序顺序排列。在此步骤中,我们需要对配对进行排序。 ![]() 根据步骤 3,选择前两个配对并将它们组合起来,我们得到 ![]() 我们观察到父节点没有频率,所以我们必须给它分配频率。父节点的频率将是其左右子节点的频率之和,即 2+4=6。 ![]() 再次,我们检查配对是否按排序顺序排列。在此步骤中,我们需要对配对进行排序。排序后,树的外观如下: ![]() 根据步骤 3,选择前两个配对并将它们组合起来,我们得到 ![]() 我们观察到父节点没有频率,所以我们必须给它分配频率。父节点的频率将是其左右子节点的频率之和,即 5+6=11。 ![]() 因此,我们得到一棵单一的树。 最后,我们将通过上述树找到每个字符的编码。为每条边分配权重。请注意,每个左边缘的权重为 0,右边缘的权重为 1。 ![]() 我们观察到输入字符仅出现在叶节点中,而内部节点具有空值。为了找到每个字符的哈夫曼编码,从根节点到需要查找编码的特定字符的叶节点遍历哈夫曼树。该表描述了每个字符的编码和编码长度。
我们观察到出现频率最高的字符获得了最短的编码长度,而出现频率最低的字符获得了最长的编码长度。 现在我们可以编码我们上面使用的字符串 (abracadabra)。 (ii) 字符串的平均编码长度可以使用以下公式确定哈夫曼树的平均编码长度 = { (5 x 1) + (2 x 3) + (1 x 4) + (1 x 4) + (2 x 2) } / (5+2+1+1+2) = 2.09090909 (iii) 编码字符串的长度可以使用以下公式确定编码消息的长度 = 11 x 2.09090909 = 23 位 哈夫曼编码算法哈夫曼算法是一种贪婪算法。因为在每个阶段,算法都会寻找最佳可用选项。 哈夫曼编码的时间复杂度为O(nlogn)。 其中 n 是给定文本中的字符数。 哈夫曼解码哈夫曼解码是一种将编码数据转换为初始数据的技术。正如我们在编码中看到的,哈夫曼树是为输入字符串构建的,字符根据它们在树中的位置进行解码。解码过程如下:
子节点包含输入字符。它被分配由连续的 0 和 1 组成的编码。解码字符串的时间复杂度为O(n), 其中 n 是字符串的长度。 哈夫曼编码和解码 Java 程序在以下程序中,我们使用优先级队列、堆栈和树等数据结构来设计压缩和解压缩逻辑。我们将基于广泛使用的哈夫曼编码算法技术来构建我们的实用程序。 HuffmanCode.java 输出 Huffman Codes of the characters are: {p=000, a=110, t=111, v=001, i=010, j=011, n=100, o=101} The initial string is: javatpoint The encoded string is: 011110001110111000101010100111 The decoded string is: javatpoint |
在多线程编程中,thread 是一个部分。为了编写一个使用 2 个线程打印奇偶数的代码,需要具备多线程的知识。现在,我们需要按自然顺序打印出奇数和偶数,直到...
11 分钟阅读
与其他编程语言一样,Java 也有一些常量。在上一节中,我们讨论了 Java 常量以及如何声明常量。因此,在本节中,我们将讨论 Java 中常量的唯一类型以及如何使用它。常量是指无法...
7 分钟阅读
Strictfp 关键字在 Java 中的作用 Java strictfp 关键字可确保在浮点变量上执行操作时,您将在每个平台上获得相同的结果。精度可能因平台而异,这就是 Java 编程语言提供 strictfp 关键字的原因,因此...
阅读1分钟
? 在 Java 中,SSL 证书可以定义为一种数字证书,它用于在服务器和使用 SSL/TLS(安全套接层/传输层安全)协议的客户端之间提供安全、加密和连接。在各个领域...
5 分钟阅读
Java.util.List是Collection的一个派生接口。它是一组有序的对象,允许存储重复值。List由于维护插入顺序,因此允许按位置访问和插入元素。Vector、Stack、LinkedList和ArrayList类用于实现List...
阅读 6 分钟
Toeplitz 矩阵是线性代数中的一种特殊类型的矩阵,其中从左到右的每个下降对角线包含相同的元素。它是以数学家 Otto Toeplitz 的名字命名的。Toeplitz 矩阵是大小为 n×n 的方阵,其中每个...
阅读 12 分钟
Java 中的 IdentityHashMap 类 IdentityHashMap 类类似于 HashMap 类。它实现了 AbstractMap 类。然而,它在比较键(或值)时使用引用相等性而不是对象相等性。它不是 Map 的通用实现。虽然此类实现了...
阅读 12 分钟
在竞争性编程中,使用高效可靠的库确实对生产力和性能产生了巨大的影响。在本教程中,我们将重点介绍 Collection Framework 中最重要的容器。Java 标准库包含以下数据结构:1. ArrayList ArrayList 是……的一部分
阅读 24 分钟
要深入了解一种编程语言,应该练习具体的编程语言程序。通过实际操作程序,您将更好地学习和理解编程语言,并且在实践中实现时永远不会忘记这些概念。特别是如果您是初学者,那么...
阅读 8 分钟
字符串反转是一个常见的编程问题,其中需要反转给定的字符串,使得字符串的最后一个字符变成第一个字符,反之亦然。然而,在保留空格的情况下,空格的顺序应该在...中得到维护。
阅读9分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India