哈夫曼编码(霍夫曼、赫夫曼)

news2025/1/11 1:35:42

一、发展历史

哈夫曼使用自底向上的方法构建二叉树。

哈夫曼编码的基本方法是先对图像数据扫描一遍,计算出各种像素出现的概率按概率的大小指定不同长度的唯一码字这种长度不同的编码方式称为变长编码,对应的长度相同的编码方式叫定长编码),由此得到一张该图像的哈夫曼码表。编码后的图像数据记录的是每个像素的码字,而码字与实际像素值的对应关系记录在码表中
(同理也可对字符数据,扫描字符数据,计算各字符出现概率,按概率的大小指定不同长度的唯一码字,得到一段该字符数据的哈夫曼码表,编码后的字符数据记录是每个字符的码字,而码字与实际字符的对应关系记录在码表中)

该方法完全依据字符出现概率来构造异字头(即任一字符的编码不会是另一字符编码的前缀)的平均长度最短的码字,有时称之为最佳编码,一般就称Huffman编码。

二、原理


a图表示将新合并的支路排到等概率的最上支路,b图则是排到等概率的最下支路

设某信源产生有五种符号 u 1 , u 2 , u 3 , u 4 和 u 5 u_1,u_2,u_3,u_4和u_5 u1u2u3u4u5,对应概率 p 1 = 0.4 , p 2 = 0.1 , p 3 = p 4 = 0.2 , p 5 = 0.1 p_1=0.4,p_2=0.1,p_3=p_4=0.2,p_5=0.1 p1=0.4p2=0.1p3=p4=0.2p5=0.1。首先,将符号按照概率由大到小排队,如图1所示。编码时,从最小概率的两个符号开始,可选其中一个支路为0,另一支路为1。这里,我们选上支路为0,下支路为1。再将已编码的两支路的概率合并,并重新排队。多次重复使用上述方法直到合并概率归一时为止。
从上图中(a)和(b)可以看出,两者虽平均码长相等,但同一符号可以有不同的码长,及编码方法并不唯一,其原因是两支路概率合并后重新排队时,可能出现几个支路概率相等,造成排队方法不唯一。一般,若将新合并后的支路排到等概率的最上支路,将有利于缩短码长方差,且编出的码更接近于等长码。 这里上图(a)的编码比(b)好。

哈夫曼码的码字(各符号的代码)是异前置码字,即任一码字不会是另一码字的前面部分,这使各码字可以连在一起传送,中间不需另加隔离符号,只要传送时不出错,收端仍可分离各个码字,不致混淆。

三、定理

哈夫曼编码的具体方法:先按出现的概率大小排队,把两个最小的概率相加,作为新的概率和剩余的概率重新排队,再把最小的两个概率相加,再重新排队,直到最后变成1。每次相加时都将“0”和“1”赋与相加的两个概率,读出时由该符号开始一直走到最后的“1”, 将路线上所遇到的“0”和“1”按最低位到最高位的顺序排好,就是该符号的赫夫曼编码。

3.1 举例

U :( a 1 , a 2 , a 3 , a 4 , a 5 , a 6 , a 7 ) U:(a_1,a_2,a_3,a_4,a_5,a_6,a_7) U:(a1,a2,a3,a4,a5,a6,a7
值分别为:
0.20 0.20 0.20 0.19 0.19 0.19 0.18 0.18 0.18 0.17 0.17 0.17 0.15 0.15 0.15 0.10 0.10 0.10 0.01 0.01 0.01
生成的哈哈夫曼树如下:

哈夫曼编码为:
a 1 a_1 a1:01
a 2 a_2 a2:00
a 3 a_3 a3:111
a 4 a_4 a4:110
a 5 a_5 a5:101
a 6 a_6 a6:1000
a 7 a_7 a7:1001
用赫夫曼编码所得的平均比特率: ∑ 码长 ∗ 出现概率 \sum码长 *出现概率 码长出现概率
上例为:0.2 * 2+0.19 * 2+0.18 * 3+0.17 * 3+0.15 * 3+0.1 * 4+0.01 *4=2.72bit

四、类型

4.1 静态哈夫曼编码

1.哈夫曼编码时如何实现数据的压缩和解压缩的呢?
在计算机当中,数据的存储和加工都是以字节为基本单位的,一个西文字符要通过一个字节来表示,而一个汉字就要用两个字节,我们把这种每一个字符都通过相同的字节数来表达的编码形式称为定长编码。
以西文为例,例如我们要在计算机当中存储这样一句话:I am a teacher. 就需要15个字节,也就是120(15*8)个二进制位的数据来实现。
与这种定长编码不同的是,哈夫曼编码是一种变长编码它根据字符出现的概率来构造平均长度最短的编码,也就是说,如果一个字符在一段文档当中出现的次数多,它的编码就响应的短,如果一个字符在一段文档当中出现的次数少,它的编码就相应的长。当编码中,各码字的长度严格按照对应符号出现的概率大小进行逆序排列时,则编码的平均长度时最小的,这就是哈夫曼编码实现数据压缩的基本原理。

2.获取一段数据的哈夫曼编码三步骤
1.扫描需编码的数据,统计原数据中各字符出现的概率。
2.利用得到的概率值创建哈夫曼树。
3.对哈夫曼树进行编码,并把编码后得到的码字存储起来。

3.如何保证任意一个字符的编码都不会成为其他编码的前缀呢?(方便接收端的译码过程)
因为定长编码已经用相同的位数这个条件保证了任一字符的编码都不会成为其它编码的前缀,所以某一字符的编码成为另一字符编码前缀这种情况只会出现在变长编码中,要想避免这种情况,必须用一个条件来制约变长编码,这个条件就是要想成为压缩编码,变长编码就必须是前缀编码(任一字符的编码不能是另一字符编码的前缀)。
那么哈夫曼编码是否是前缀编码呢?观察上图由 ( a 1 , a 2 , a 3 , a 4 , a 5 , a 6 , a 7 ) (a_1,a_2,a_3,a_4,a_5,a_6,a_7) a1,a2,a3,a4,a5,a6,a7构成的编码树,可以发现要想成为某一字符的编码前缀,必须是该字符的父亲节点、祖孙节点…等有辈分差关系的节点在哈夫曼树中,文档中的数据字符全都分布在哈夫曼树的叶子节点,从而保证了哈夫曼编码当中的任何一个字符都不能是另一个字符编码的前缀,也就是说哈夫曼编码是一种前缀编码,也就保证了解压缩过程当中译码的准确性。

4.哈夫曼编码的解压缩过程
将编码严格按照哈夫曼树进行翻译就可以了,例如遇到1000,就可以顺着哈夫曼树找到 a 6 a_6 a6,遇到111,就可以顺着哈夫曼树找到 a 3 a_3 a3,以此类推,就可以很顺利的找到原来所有的字符。

5.哈夫曼编码的重要性
哈夫曼编码是一种一致性编码,有着非常广泛的应用,例如在JPEG文件中,就应用了哈夫曼编码来实现最后一步的压缩,在数字电视大力发展的今天,哈夫曼编码成为了视频信号的主要压缩方式。哈夫曼编码出现结束了熵编码不能实现最短编码的历史,也使哈夫曼编码成为一种非常重要的无损编码。

6.静态哈夫曼方法的缺点
静态哈夫曼编码的最大缺点就是它需要对原始数据进行两遍扫描

  • 第一遍统计原始数据中各字符出现的频率,利用得到的频率值创建哈夫曼树并将树的有关信息保存起来,便于压缩时使用;
  • 第二遍则根据前面得到的哈夫曼树对原始数据进行编码,并将编码信息存储起来。这样如果用于网络通信中,将会引起较大的时延。

对于文件压缩这样的应用场合,额外的磁盘访问将会降低该算法的数据压缩速度

4.2 动态哈夫曼编码(适应性哈夫曼编码)

动态哈夫曼编码允许在符号正在传输时构建代码,允许一次编码并适应数据中变化的条件,即随着数据流的到达,动态地收集和更新符号的概率(频率) 。一遍扫描的好处是使得源程序可以实时编码,但由于单个丢失会损坏整个代码,因此它对传输错误更加敏感。

动态哈夫曼编码与解码过程的链接:https://blog.csdn.net/weixin_43838265/article/details/117324663

动态哈夫曼编码方法对数据编码的依据是动态变化的哈夫曼树,也就是说,对于第n+1个字符编码时根据原始数据中前n个字符得到的哈夫曼树来进行的,压缩和解压具有相同的初始化树,每处理完一个字符,压缩和解压方使用相同的算法修改哈夫曼树,因而该方法不需要为解压而保存树的有关信息。压缩和解压一个字符所需的时间与该字符的编码长度成正比,因而该过程可以实时进行。

五、应用举例

哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称“熵编码法”),用于数据的无损耗压缩。这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。这种方法是由David.A.Huffman发展起来的。 例如,在英文中,e的出现概率很高,而z的出现概率则最低。当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。若能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/753918.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关闭Vue CLI(脚手架)中的语法检查

1.创建一个名为vue.config.js的文件,与package.json文件平级 参考官方文档:Home | Vue CLI (vuejs.org) 2.将下面代码复制进vue.config.js文件中 module.exports{lintOnSave:false;//关闭语法检查 }

c++计算贝塞尔曲线(折线平滑为曲线)坐标方法

效果可查看上一篇博文&#xff1a;js手动画平滑曲线&#xff0c;贝塞尔曲线拟合【代码】js手动画平滑曲线&#xff0c;贝塞尔曲线拟合。https://blog.csdn.net/qiufeng_xinqing/article/details/131711963?spm1001.2014.3001.5502 代码如下&#xff1a; #include <cmath&…

10.6.1 【Linux】撷取命令: cut, grep

cut cut 主要的用途在于将“同一行里面的数据进行分解&#xff01;”最常使用在分析一些数据或文字数据的时候。这是因为有时候我们会以某些字符当作分区的参数&#xff0c;然后来将数据加以切割&#xff0c;以取得我们所需要的数据。 grep 10.6.2 排序命令&#xff1a; sort,…

最火爆的大模型框架LangChain七大核心及案例剖析上(一)

最火爆的大模型框架LangChain七大核心及案例剖析上 10.1 Models解析及案例剖析 本节正式进入当前开源界最火爆的大模型开发框架LangChain的部分,会讲解整个LangChain解决的问题及它的工作机制,通过一个“LangChain GPT内容创建者”(“LangChain GPT Content Creator”)的具体…

第九章:RefineNet——多路径细化网络用于高分辨率语义分割

0.摘要 最近&#xff0c;非常深的卷积神经网络&#xff08;CNN&#xff09;在目标识别方面表现出色&#xff0c;并且也是密集分类问题&#xff08;如语义分割&#xff09;的首选。然而&#xff0c;在深度CNN中&#xff0c;重复的子采样操作&#xff08;如池化或卷积跳跃&#x…

Matplotlib figure图形对象

通过前面的学习&#xff0c;我们知道matplotlib.pyplot模块能够快速地生成图像&#xff0c;但如果使用面向对象的编程思想&#xff0c;我们就可以更好地控制和自定义图像。 在 Matplotlib 中&#xff0c;面向对象编程的核心思想是创建图形对象&#xff08;figure object&#…

第十三章——类继承

面向对象编程的主要目的之一是提供可重用的代码。&#xff08;重用经过测试的代码比重新编写代码要好的多&#xff09; C类提供了更高层次的重用性。很多厂商提供了类库&#xff0c;类组合了数据表示和类方法&#xff0c;因此提供了比函数库更加完整的程序包。通常类库是以源代…

文件IO_文件读写(附Linux-5.15.10内核源码分析)

目录 1.什么是文件偏移量&#xff1f; 1.1 文件偏移量介绍 1.2 文件偏移量重点 1.3 文件偏移量工作原理 2.文件偏移量设置 2.1 lseek函数 2.2 lseek内核源码分析 3.写文件 3.1 write函数 3.2 write内核源码分析 4.读文件 4.1 read函数 4.2 read内核源码分析 5.文…

物流难统计、难管理?学会这招,问题迎刃而解

在当今数字化的时代&#xff0c;商家面临着诸多物流挑战。物流数据人工统计成本高、管理难、决策难是很常见的问题。本文将探讨如何通过智能数据分析解决这些问题&#xff0c;帮助商家提升物流效率和管理能力。 物流数据人工统计&#xff0c;难决策 物流数据沉淀全靠人工线下…

Vue3_简介、CompositionVPI、新的组件

文章目录 Vue3快速上手1.Vue3简介2.Vue3带来了什么1.性能的提升2.源码的升级3.拥抱TypeScript4.新的特性 一、创建Vue3.0工程1.使用 vue-cli 创建2.使用 vite 创建 二、常用 Composition API1.拉开序幕的setup2.ref函数3.reactive函数4.Vue3.0中的响应式原理vue2.x的响应式Vue3…

labview实现呼吸灯颜色渐变效果

呼吸灯效果具有美好的视觉观感&#xff0c;前一段时期感受了一位大佬在MCU中实现呼吸灯颜色渐变效果&#xff0c;很是震撼。这引起了我的兴趣&#xff0c;本文则是实现一种呼吸灯效果(主要在于颜色的渐变体现)。 程序整体视图 程序框图 公式节点程序 int red_is_0 red 0 ?…

探索MR与AIGC技术的发展机遇:教育、医疗领域的前景展望

在当今科技迅猛发展的时代&#xff0c;混合现实&#xff08;MR&#xff09;和增强智能生成创作&#xff08;AIGC&#xff09;技术正逐渐成为教育、医疗领域中的关键驱动力。这两项前沿技术的结合为我们带来了无限的可能性和创新的机遇。 MR技术在教育领域中的发展与机遇是广泛而…

非洲秃鹫优化算法(AVOA)(含MATLAB代码)

先做一个声明&#xff1a;文章是由我的个人公众号中的推送直接复制粘贴而来&#xff0c;因此对智能优化算法感兴趣的朋友&#xff0c;可关注我的个人公众号&#xff1a;启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法&#xff0c;经典的&#xff0c;或者是近几年…

LayUI框架实现OA会议系统——增删改查

目录 前言 1. 配置准备 1.1 Layui框架 1.2 mysql数据库表 1.3 用户管理JSP页面 1.4 新增、修改用户共用界面 2. 后台编写 2.1 编写UserDao类增删改查方法 2.2 R工具类 2.3 BaseDao数据库查询方法 2.4 UserAction控制器类 3. 前台JS编写 3.1 userManage页面JS 3.2…

测试报告?Python自动化测试-Allure测试报告使用大全,一篇全通透

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 安装并配置环境变…

工业相机的基础参数释义

景深&#xff1a; 可以清晰拍摄被测物的距离范围。 工作距离&#xff1a; 相机镜头至被测物的距离。 物像距离&#xff1a; 被测物至芯片靶面的距离。 像元尺寸&#xff1a; 一个像素在长和宽方向上所代表的实际大小&#xff0c;单位通常为微米。像元尺寸越大&#xff0c;分辨率…

记录stm32c8t6使用TIM4_CH1、TIM4_CH2输出PWM波控制编码电机出现的问题

由于之前是使用PB9、PB7引脚即TIM4_ch3\TIM4_ch4&#xff0c;由于项目更改为c8t6的PB、PB7引脚&#xff08;TIM4_ch3\TIM4_ch4&#xff09; 改为配置后发现只有一边的轮子可以转到&#xff0c;明明配置没什么问题&#xff0c;编译也没有报错&#xff0c;最后将pwm的调制模式更改…

Android 进程与进程之间的通信--AIDL详细教程,以传递对象为例,两个app实现

我这里案例是 通过 IPC 传递对象 &#xff08;以DemoBean类为例&#xff09; 如下&#xff1a; AIDL 使用一种简单语法&#xff0c;允许您通过一个或多个方法&#xff08;可接收参数和返回值&#xff09;来声明接口。参数和返回值可为任意类型&#xff0c;甚至是 AIDL 生成的其…

TypeScript 学习笔记 环境安装-类型注解-语法细节-类-接口-泛型

文章目录 TypeScript 学习笔记概述TypeScript 开发环境搭建 类型注解类型推断 数据类型JS的7个原始类型Array数组object、Object 和 {}可选属性 ? 和 可选链运算符?. function函数TS类型: any类型 | unknow类型TS类型: void类型TS类型&#xff1a;never类型 &#xff08;几乎…

数据库应用:CentOS 7离线安装MySQL与Nginx

目录 一、理论 1.安装依赖 二、实验 1.离线安装MySQL与Nginx 2.离线安装Nginx 三、问题 1.执行nginx -v命令报错 四、总结 一、理论 1.安装依赖 &#xff08;1&#xff09;概念 安装依赖是指在软件开发中&#xff0c;为了运行或者编译一个程序或者库&#xff0c;在计…