哈夫曼树与哈夫曼编码

简介: 哈夫曼编码 哈夫曼编码(Huffman Coding)是一种编码方式,也称为“赫夫曼编码”,是David A. Huffman1952年发明的一种构建极小多余编码的方法。在计算机数据处理中,哈夫曼编码使用变长编码表对源符号进行编码,出现频率较高的源符号采用较短的编码,出现频率较低的符号采用较长的编码,使编码之后的字符串字符串的平均长度 、期望值降低,以达到无损压缩数据的目的。

哈夫曼编码

哈夫曼编码(Huffman Coding)是一种编码方式,也称为“赫夫曼编码”,是David A. Huffman1952年发明的一种构建极小多余编码的方法。
在计算机数据处理中,哈夫曼编码使用变长编码表对源符号进行编码,出现频率较高的源符号采用较短的编码,出现频率较低的符号采用较长的编码,使编码之后的字符串字符串的平均长度 、期望值降低,以达到无损压缩数据的目的。

举个例子,现在我们有一字符串:this is an example of a huffman tree

这串字符串有36个字符,如果按普通方式存储这串字符串,每个字符占据1个字节,则共需要36 * 1 * 8 = 288bit。

经过分析我们发现,这串字符串中各字母出现的频率不同,如果我们能够按如下编码:

字母 频率 编码 --- 字母 频率 编码
space 7 111   s 2 1011
a 4 010   t 2 0110
e 4 000   l 1 11001
f 3 1101   o 1 00110
h 2 1010   p 1 10011
i 2 1000   r 1 11000
m 2 0111   u 1 00111
n 2 0010   x 1 10010

编码这串字符串,只需要:
(7+4+4)x3 + (3+2+2+2+2+2+2)x4 + (1+1+1+1+1+1)x 5 = 45+60+30 = 135bit(WPL)
编码这串字符串只需要135bit!单单这串字符串,就压缩了288-135 = 153bit。

如何获取每个字符串的编码呢?这就需要哈夫曼树了。
源字符编码的长短取决于其出现的频率,我们把源字符出现的频率定义为该字符的权值。

哈夫曼树

哈夫曼又称最优二叉树。是一种带权路径长度最短的二叉树。

定义

假设有n个权值{w1,w2,w3,w4...,wn},构造一棵有n个节点的二叉树,若树的带权路径最小,则这颗树称作哈夫曼树。

术语与解释

对10,20,30,40构建哈夫曼树。

 

  • 路径与路径长度:从树中一个节点到另一个节点之间的分支构成了两个节点之间的路径,路径上的分支数目称作路径长度。若规定根节点位于第一层,则根节点到第H层的节点的路径长度为H-1.如树b:100到60 的路径长度为1;100到30的路径长度为2;100到20的路径长度为3。

  • 树的路径长度:从根节点到每一节点的路径长度之和。树b的路径长度为1+1+2+2+3+3 = 12.
  • 节点的权:将树中的节点赋予一个某种含义的数值作为该节点的权值,该值称为节点的权;
  • 带权路径长度:从根节点到某个节点之间的路径长度与该节点的权的乘积。例如树b中,节点10的路径长度为3,它的带权路径长度为10 * 3 = 30;
  • 树的带权路径长度:树的带权路径长度为所有叶子节点的带权路径长度之和,称为WPL。树b的WPL = 1x40+2x30+3x10+3x20 = 190.而哈夫曼树就是树的带权路径最小的二叉树

构造步骤

假设有n个权值,则构造出的哈夫曼树有n个叶子节点.n个权值记为{w1,w2,w3...wn},哈夫曼树的构造过程为:

  1. 将w1,w2,w3...wn看成具有n棵树的森林,每棵树仅有一个节点。
  2. 从森林中,选取两棵根节点权值最小的树,两棵树分别作为左子树与右子树,构建一棵新树。新树的权值等于左右子树权值之和。
  3. 从森林中删除两棵权值最小的树,将构建完成后的新树加入森林中。
  4. 重复2、3步骤,直到森林只剩一棵树为止。这棵树便是哈夫曼树。

 上图树b为一棵哈夫曼树,它的叶子节点为{10,20,30,40},以这4个权值构建树b的过程为:

 

为{10,20,30,40}这四个权值构建了哈夫曼编码后,我们可以由如下规则获得它们的哈夫曼编码:

  • 从根节点到每一个叶子节点的路径上,左分支记为0,右分支记为1,将这些0与1连起来即为叶子节点的哈夫曼编码。

 

(字母)权值 编码
10 100
20 101
30 11
40 0

由此可见,出现频率越高的字母(也即权值越大),其编码越短。这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。

 

目录
相关文章
|
11月前
|
存储 人工智能 算法
【AI系统】计算与调度
本文探讨了计算与调度的概念,特别是在神经网络和图像处理中的应用。通过分离算法定义和计算组织,Halide 等工具能够显著提升图像处理程序的性能,同时保持代码的简洁性和可维护性。文章详细介绍了计算与调度的基本概念、调度树的构建与约束,以及如何通过调度变换优化计算性能。此外,还讨论了自动调优方法在大规模调度空间中的应用,展示了如何通过探索和预测找到最优的调度方案。
238 0
|
3月前
|
运维 监控 Java
Tomcat配置参数connection-timeout的详细解析和应用讨论
`connection-timeout` 的配置需要根据实际的应用场景、服务器性能、网络环境以及用户行为来决定。因此,开发和运维团队通常需要结合应用特点和监控数据,经过一系列的测试和调优,来确定一个既能保证用户体验,又能维护服务器稳定性和安全性的最优值。
469 0
|
11月前
|
存储 文件存储 数据库
在飞牛 NAS 上部署宝塔面板
飞牛NAS成为家庭私有云热门选择,通过部署宝塔面板,用户可以轻松搭建网站及各类Web应用,如相册、笔记、影视库等。本文介绍如何在飞牛NAS上安装宝塔面板,实现快速配置网站、数据库等服务,特别适合新手操作。
1733 5
在飞牛 NAS 上部署宝塔面板
|
10月前
|
数据挖掘 数据处理 开发者
Python3 自定义排序详解:方法与示例
Python的排序功能强大且灵活,主要通过`sorted()`函数和列表的`sort()`方法实现。两者均支持`key`参数自定义排序规则。本文详细介绍了基础排序、按字符串长度或元组元素排序、降序排序、多条件排序及使用`lambda`表达式和`functools.cmp_to_key`进行复杂排序。通过示例展示了如何对简单数据类型、字典、类对象及复杂数据结构(如列车信息)进行排序。掌握这些技巧可以显著提升数据处理能力,为编程提供更强大的支持。
494 10
|
机器学习/深度学习 编解码 负载均衡
MoH:融合混合专家机制的高效多头注意力模型及其在视觉语言任务中的应用
本文提出了一种名为混合头注意力(MoH)的新架构,旨在提高Transformer模型中注意力机制的效率。MoH通过动态注意力头路由机制,使每个token能够自适应选择合适的注意力头,从而在减少激活头数量的同时保持或提升模型性能。实验结果显示,MoH在图像分类、类条件图像生成和大语言模型等多个任务中均表现出色,尤其在减少计算资源消耗方面有显著优势。
397 1
|
算法 中间件 API
使用漏桶和令牌桶实现API速率限制
本文介绍如何在 Go 语言的 Gin 框架中使用漏桶算法和令牌桶算法实现 API 限流,以保护系统资源,防止过载和恶意攻击,确保服务稳定。通过具体代码示例展示了两种算法的应用方法。
213 2
|
JavaScript 前端开发
【Vue 3】如何实现动态表单生成器的拖拽功能?
【Vue 3】如何实现动态表单生成器的拖拽功能?
|
弹性计算 监控 Linux
ECS实例问题之无法连接443端口如何解决
ECS实例指的是在阿里云ECS服务中创建的虚拟计算环境,用户可在此环境中运行应用程序和服务;本合集将介绍ECS实例的创建、管理、监控和维护流程,及常见问题处理方法,助力用户保障实例的稳定运行。
|
机器学习/深度学习 算法 数据库
【功能超全】基于OpenCV车牌识别停车场管理系统软件开发【含python源码+PyqtUI界面+功能详解】-车牌识别python 深度学习实战项目
【功能超全】基于OpenCV车牌识别停车场管理系统软件开发【含python源码+PyqtUI界面+功能详解】-车牌识别python 深度学习实战项目
|
Ubuntu 关系型数据库 MySQL
Ubuntu彻底卸载MySQL,彻底!亲测!
Ubuntu彻底卸载MySQL,彻底!亲测!
2066 0