哈夫曼树与哈夫曼编码

简介: 哈夫曼树与哈夫曼编码

哈夫曼树

给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。


树节点间的边相关的数叫做权。从树中的一个节点到另一个节点之间的分支构成两个点之间的路径,路径上的分支数目称作路径长度。


例如,如下图:



从根结点100到C3的路径长度为4,也就是图中的根结点100到达C3的路径长度为4。


树的路径长度就是从树根到每一个节点的路径长度之和。二叉树的路径长度就为1+1+2+2+2+2+3+3+3+3+4+4+4+4=38。如果考虑带权的节点,节点的带权的路径长度就是从该节点到树根之间的路径长度乘该节点的权。数的带权路径长度就是所有叶子节点的带权路径长度之和。带权路径长度(WPL)最小的二叉树称作哈夫曼树。


如何构造哈夫曼树

下面我们以【3、4、5、6、10、25、36、11】为例来画出哈夫曼树(数字大小代表权重大小,越大的权重越大)


第一步:按从小到大排序。

【3、4、5、6、10、25、36、11】→【3、4、5、6、10、11、25、36】


第二步:选最小两个数画出一个树,最小数为3和4。

构成第一个二叉树,根结点为7,左子树为3,右子树为4。



之后一直重复第一、第二步:排序然后取两个最小值。实际就是一个递归过程


排序:

取两个最小数5和6,构成另一个二叉树,根结点11,左子树为5,右子树为6。



再取两个最小数第一个二叉树的根结点7和未取出的数10,组成一个新的二叉树如图:



再取一个数11,和另一个根结点相结合,组成一个新的二叉树:



再取出两个最小数字,现在两个最小数字是两个二叉树的根结点,所以如下图:



再取两个最小数25和36,组成新的二叉树:



再取两个最小数的根结点,如下图所示,组成新的二叉树:



这个过程就是构造哈夫曼树的过程,也是最小二叉树。


哈夫曼编码

哈夫曼研究这种最优树的目的是为了解决当年远距离通信(主要是电报)的数据传输的最优化问题。


比如我们继续用上边的图来做这个,正好图片上有编码了。不管是以前还是现在,网络的数据传输都是用的计算机最基础的语言,0和1,图上的C1到C8八个字符串,和图上附带的它们自带的权值,带表了它们在数据中出现次数的量,如何才能用最少的数据存储,传出最大的数据信息呢,这就是哈夫曼编码的作用。



根据上边的构造哈夫曼树,我们把左子树的边用0表示,把右子树的边用1表示,那就得到如下的二进制编码。


C1:0100


C2:10


C3:0000


C4:0101


C5:001


C6:011


C7:11


C8:0001


用到的次数越少,那么编码则就越长,用到的次数越多,则编码就越短,当这个次数足够多的时候,差距才会比较明显。


如果用字母表示,可能会更明显,看下边的一个例子:


字母表示:

比如我们有一段文字“BADCADFEED”,显然用二进制数字(0和1)表示是很自然的想法。


image.png


这样真正传输的数据就是“001000011010000011101100100011”,对方接收时同样按照3位一组解码。如果一篇文章很长,这样的二进制串也非常的可怕。而且事实上,每个字母或者汉字的出现频率是不同的。


假设六个字母的频率为A 27,B 8, C 15, D 15 , E 30, F 5,合起来正好是100%,那就意味着我们完全可以用哈夫曼树来规划它们。


左图为构造哈夫曼树的过程的权值显示。右图为将权值左分支改为0,右分支改为1后的哈夫曼树。

image.png



我们对这六个字母用其从树根到叶子所经过的路径的0或1来编码,可以得到下表:


image.png


image.png



也就是说我们的数据被压缩了,节约了大概17%的存储或传输成本。随着字符的增加和多字符权重的不同,这种压缩会更显出优势来。


上例子,摘自diligentyang


好的,总结来说,哈夫曼树在一定程度上缓解了传输数据量过大,大大节省了传输成本。


相关文章
|
算法 C语言 C++
二叉树三种遍历(动态图+代码深入理解)
二叉树三种遍历(动态图+代码深入理解)
3169 3
二叉树三种遍历(动态图+代码深入理解)
|
Ubuntu 数据安全/隐私保护 Windows
Vagrant快速搭建Ubuntu虚拟机环境
Vagrant快速搭建Ubuntu虚拟机环境
1193 0
Vagrant快速搭建Ubuntu虚拟机环境
|
SQL 关系型数据库 分布式数据库
PostgreSQL 在线修改数据类型 - online ddl 方法之一
标签 PostgreSQL , online ddl , trigger , ddl 事务 背景 有张表的主键id是serial,但现在不够了,需要升级成bigserial,有什么优雅的方法吗?我看下来好像会锁表很久(因为数据量挺大) 如果直接alter table,由于数据类型从4字节改成了8字节,而tuple结构是在METADATA里面的,不是每行都有,所以DEFORM需要依赖METADATA,目前来说,这种操作需要rewrite table。
4444 0
|
8月前
|
监控 搜索推荐 Linux
top 与 htop 实时监控
`top` 和 `htop` 是 Linux 系统中常用的实时监控工具。`top` 命令默认每 3 秒刷新一次,显示系统整体概览和进程列表,支持基本的进程管理操作。`htop` 则提供更友好的界面,带有彩色条形图、鼠标支持和更多交互功能,如进程搜索、优先级调整等。两者都适用于监控系统资源和管理进程,但 `htop` 功能更丰富,用户体验更好,适合复杂场景。
214 8
|
编解码
FFT_频谱分析(数字信号处理)
用FFT对信号作频谱分析是学习数字信号处理的重要内容。经常需要进行谱分析的信号是模拟信号和时域离散信号。对信号进行谱分析的重点在于频谱分辨率及分析误差。频谱分辨率D和频谱分析的点数N直接相关,其分辨率为2π/N 。因此2π/N≤D,可以据这个公式确定频率的分辨率。 FFT分析频谱的误差在于得到的是离散谱,而信号(非周期信号)是连续谱,只有当N较大时,离散谱的包络才能逼近于连续谱。因此N要适当选择大一些。 周期信号的频谱是离散谱,只有用整数倍周期的长度作FFT,得到的离散谱才能代表周期信号的频谱。如果不知道信号周期,可以尽量选择信号的观察时间长一些。 对模拟信号进行谱分析时,首先要按照
988 1
FFT_频谱分析(数字信号处理)
|
安全 云栖大会 云计算
首批Well-Architected生态合作伙伴揭晓,齐聚2024云栖大会
在帮助企业客户上好云、用好云、管好云的道路上,阿里云始终坚持开放合作的理念,不断寻求与优质的生态伙伴深化合作,携手共建Well-Architected技术与服务方案。在今年的云栖大会上,共七家合作伙伴企业荣获首批「Well-Architected阿里云卓越架构生态合作伙伴」认证。
585 2
|
存储 监控 API
【云原生系列】云计算概念与架构设计介绍
**云计算**是基于互联网的计算模式,通过共享计算资源(如服务器、存储、应用程序)提供高效、可扩展、可靠、安全和经济的服务。其架构通常包括**物理层**(服务器、存储、网络设备等基础设施)、**虚拟化层**(虚拟机、容器、虚拟网络等)、**平台层**(开发、运行时、数据库服务等)和**应用层**(企业应用、Web应用、移动应用)。云计算服务有IaaS、PaaS和SaaS,广泛应用于企业IT、开发测试、大数据处理、AI和远程办公等领域。为了确保性能和可靠性,云平台采用负载均衡、自动伸缩、备份恢复、安全措施和监控故障排除等方法。
1079 1
|
JavaScript
vue父组件向子组件传值的方法
vue父组件向子组件传值的方法
458 0