Huffman树和Huffman编码

article/2025/9/29 1:17:54

文章目录

    • Huffman树的定义
      • 带权路径长度WPL
    • Huffman树的构造
      • Huffman树的特点
    • Huffman编码
      • 构造Huffman编码


Huffman树的定义

哈夫曼(Huffman)树,又称最优二叉树,是一类带权路径长度WPL最短的树。

带权路径长度WPL

要理解带权路径长度的内涵,首先需要了解的一些概念:

  • 路径:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径。
  • 路径长度:路径上的分支数目。即经过的边数。
  • 树的路径长度:从树根结点到每一个结点的路径长度之和。
  • 结点的权:结点被赋予的一个表示某种意义的数值称为该结点的权。

那么,树的带权路径长度(Weighted Path Length of Tree):树中所有叶子结点的带权路径长度之和,通常记作 W P L = ∑ i = 1 n w i l i WPL=\sum_{i=1}^n{w_i}{l_i} WPL=i=1nwili
其中 w i w_i wi为第i个叶子所带的权值, l i l_i li为该叶结点到根结点的路径长度。
WPL = ∑ ( 每个叶结点的权值 * 叶结点到根结点的路径长度 )


如下图所示,分别求三棵树的WPL:
在这里插入图片描述

(a)WPL = 7 × 2 + 5 × 2 + 2 × 2 + 4 × 2 = 36.
(b)WPL = 4 × 2 + 7 × 3 + 5 × 3 + 2 × 1 = 46.
(c)WPL = 7 × 1 + 5 × 2 + 2 × 3 + 4 × 3 = 35.
其中,图(c)中树的WPL最小,可以验证它恰好为Huffman树。


Huffman树的构造

给定n个权值分别为 w 1 w_1 w1 w 2 w_2 w2,… , w n w_n wn的结点,通过Huffman算法构造出最优二叉树,算法描述如下:

<1>将这n个结点分别作为n棵只含有一个结点的二叉树,构成森林F。
<2>构造一个新结点,从F中选取两棵根结点权值最小的树作为新结点的左、右子树,并且将新结点的权值置为左、右子树上根结点的权值之和。
<3>从F中删除刚才选出的两棵树,同时将新得到的树加入F中。
<4>重复<2>和<3>步骤,直至F中只剩下一棵树为止。


这样只看算法比较抽象,下面给出一个构造Huffman树的实例来帮助读者更好的理解和掌握Huffman构造的算法。

权值{7,5,2,4}的Huffman树的构造过程如下:

<1>将这四个权值赋予四个结点,构成森林F。
在这里插入图片描述
<2>构造一个新结点,选取根结点权值最小的两棵树c和d作为新结点的左、右子树,将新结点的权值置为c和d的权值之和6.
在这里插入图片描述

<3>从F中删除c和d两个结点,并将新得到的树加入F.
在这里插入图片描述
<4>构造一个新结点,从新F中选取根结点权值最小的两棵树,即权值为5和6的两棵树作为新结点的左、右子树,并将新结点的权值置为11.
在这里插入图片描述
<5>从F中删掉根结点权值为5和6的树,并将新得到的树加入到F中.
在这里插入图片描述
<6>此时F中只剩下两棵树,则再构建一个新结点,将这两棵树作为新结点的左、右子树,并且将新结点的权值置为18.
在这里插入图片描述

至此,F中只剩下一棵树,即为构造的对应的Huffman树。


Huffman树的特点

从Huffman树的构造过程可以看出,Huffman树具有以下特点:
1、每个初始结点最终都成为叶结点,而且权值越小的结点到根结点的路径长度越大。
2、构造过程中一共创建了n-1个结点(双分支结点),因此Huffman树中的结点总数为2n-1.
3、每次构造都选择2棵树作为新结点的孩子,因此Huffman树中不存在度为1的结点。


Huffman编码

首先给出几个概念:固定长度编码、可变长度编码、前缀编码。

  • 固定长度编码:对于待处理的一个字符串序列,若对每个字符用同样长度的二进制位表示,则称这种编码方式为固定长度编码。
  • 可变长度编码:若允许对不同的字符用不等长的二进制位表示,则这种方式成为可变长度编码。
  • 前缀编码:若没有一个编码是另一个编码的前缀,则称这样的代码为前缀编码。

目前,进行快速远距离通信的主要手段是电报,即将需要传送的文字转换成由二进制的字母组成的字符串。

1、关于固定长度编码,举一个简单的小例子:

假设需要传送的字符为’A B A C C D A’,它只有四种字符,只需要两位二进制码即可分辨。
设A、B、C、D的编码分别为00、01、10和11,则上述字符串的电文为’00010010101100’,总长为14位。
对方在接收时,可按二位一分进行译码。

2、当然,在传送电文时,希望总长度尽可能的短,如果对每个字符设计长度不等的编码,且让电文中出现次数较多的字符采用尽可能短的编码,则传送电文的总长便可减少。这就是可变长度编码

如果设A、B、C、D的编码分别为0、00、1、01,则上述7个字符的电文可转换成’00001010’,总长度为9。

但是,这样的电文无法翻译,例如传送过去的字符串中前4个字符的子串’0000’就可以有多种译法,比如’AAAA’、‘ABA’、'BB’等等。

3、因此,若要设计长短不等的编码,则必须是任一个字符的编码都不是另一个字符的编码的前缀,这种编码就叫做前缀编码

对前缀编码的解码很简单,因为没有一个码是其他码的前缀。所以,可以识别出第一个编码,将它翻译为原码,再对余下的编码重复同样的解码操作。
例如,0、101、100是前缀编码。那么00101100可以被唯一地分析为0、0、101和100。


那么如何设计前缀编码呢?可以利用二叉树来设计二进制的前缀编码。
例如下图,其4个叶子结点分别表示A、B、C、D这四个字符,且约定左分支表示字符’0’,右分支表示字符’1’,则可以从根结点到叶子结点的路径上分支字符组成的字符串作为该叶子结点字符的编码。如此得到的必为二进制前缀编码。
在这里插入图片描述


构造Huffman编码

如何得到使电文总长最短的二进制前缀编码呢?其实使用Huffman树得到的Huffman编码即为总长最短的二进制前缀编码,称为Huffman编码

证明:假设每种字符在电文中出现的次数为 w i w_i wi,其编码长度为 l i l_i li,电文中有n种字符,则电文总长为 ∑ i = 1 n w i l i \sum_{i=1}^n{w_i}{l_i} i=1nwili
对应到二叉树上,若置 w i w_i wi为叶子结点的权, l i l_i li恰为从根到叶子结点的路径长度,则 ∑ i = 1 n w i l i \sum_{i=1}^n{w_i}{l_i} i=1nwili恰为二叉树上带权路径长度,而这个带权路径长度最短时的二叉树就是Huffman树,由此得到的二进制前缀编码便称为Huffman编码


构造Huffman编码的具体步骤
(其实就是先构造出Huffman树,然后按照左0右1或者左1右0的原则进行编码即可)
给定n个频率(作为权值)分别为 w 1 w_1 w1 w 2 w_2 w2,… , w n w_n wn的字符(作为独立结点).
<1>将这n个结点分别作为n棵只含有一个结点的二叉树,构成森林F。
<2>构造一个新结点,从F中选取两棵根结点权值最小的树作为新结点的左、右子树,并且将新结点的权值置为左、右子树上根结点的权值之和。
<3>从F中删除刚才选出的两棵树,同时将新得到的树加入F中。
<4>重复<2>和<3>步骤,直至F中只剩下一棵树为止。
<5>显然,所有字符结点都出现在叶子结点中。从根结点开始,左分支标’0’,右分支标’1’,那么字符的Huffman编码为从根结点到该叶子结点的路径上边标记的序列。

注:0和1究竟是表示左子树还是表示右子树没有明确规定。因此左、右结点的顺序是任意的。
所以构造出的Huffman树并不唯一,但各个Huffman树的带权路径长度相同且为最优。


用上一节构造的Huffman树写出各个字符的Huffman编码:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/BwlHQT4q.shtml

相关文章

Huffman树(哈夫曼树)

哈夫曼树又称最优二叉树&#xff0c;是一种带权路径长度最短的二叉树。所谓树的带权路径长度&#xff0c;就是树中所有的叶结点的权值乘上其到根结点的路径长度&#xff08;若根结点为0层&#xff0c;叶结点到根结点的路径长度为叶结点的层数&#xff09;。树的带权路径长度记为…

虚拟机下安装BackTrack5 (BT5)教程及BT5汉化

isare邀请您访问Backtrack中文网 http://www.backtrack.org.cn/?fromuid50397 isare邀请您访问Backtrack中文网 http://www.backtrack.org.cn/?fromuserisare PS&#xff1a;back track 安装过程中有2点要注意&#xff1a;第一&#xff1a;复制到99%的时候会等大约10来分钟&a…

bt 下载工具 deluge 配置 优化 使用

目录 Ubuntu 18 配置 deluge Deluge 安卓远程客户端 Deluge 性能调优 deluge是基于libtorrentpython的跨平台bt/pt客户端&#xff0c;适合在Linux环境下使用 deluge完全开源免费&#xff0c;对IPv6支持良好&#xff0c;性能优于transmission&#xff1b;在嵌入式设备上使用d…

BT5的U盘完整安装

BT5是什么就不用多说了&#xff0c;从网上看了许多教程&#xff0c;大多是利用unetbootin工具将ISO文件直接解压到U盘上&#xff0c;这样并不能完全使用BT&#xff0c;保存好的文件&#xff0c;重启机器后就没了&#xff0c;其实就是当做光盘使用了&#xff0c;另外还有一个方法…

有哪些好用的BT下载器?

​​​​​​2022年5个好用的 BT/ 磁力链接下载工具推荐 &#xff5c;Windows 、安卓系统 | 科技雷达 A full-featured download manager

BT是如何下载的

BT协议简介 一、BT下载是怎么来的&#xff1f; 在互联网上下载文件的方式大概有这么几种&#xff1a;FTP、HTTP、BT、eMule(电驴)等&#xff0c; 浏览器会直接支持FTP和HTTP下载&#xff0c;BT和eMule下载一般需要专用的下载软件的支持。 接下来分别简单介绍一下他们的区别&…

ed2k下载

ed2k下载 在下载ed2k资源的时候&#xff0c;浏览器一般不能直接下载&#xff0c;这个时候该怎么办呢&#xff1f; 方法一&#xff1a;下载迅雷&#xff0c;直接安装 方法二&#xff1a;使用在线工具&#xff0c;将链接转化为别的形式 https://tool.lu/urlconvert/ 方法三&am…

BT是怎么下载的

BT协议简介 一、BT下载是怎么来的? 在互联网上下载文件的方式大概有这么几种:FTP、HTTP、BT、eMule(电驴)等, 浏览器会直接支持FTP和HTTP下载,BT和eMule下载一般需要专用的下载软件的支持。 接下来分别简单介绍一下他们的区别: FTP 是 File Transfer Protocol(文件…

最好用的bt下载器qbittorrent下载安装使用教程

qBittorrent绝对是我心目中BT下载工具中的NO.1&#xff0c;虽说我平时也会用迅雷下载国内的某些资源&#xff0c;但是仍然不妨碍它是我心目中的主力下载神器&#xff01;它可以说是我最早接触的除迅雷之外的一款BT下载神器。它是完全免费的种子和磁力链接下载工具&#xff0c;最…

BT5 WIFI破解

实验环境 VMwareWorkstation 9.0 BackTrack5 R3-GNOME-32 工具说明 VMware&#xff1a;著名的虚拟机软件&#xff0c;本实验采用虚拟机环境下安装BackTrack。 BackTrack&#xff1a;是一个基于Ubuntu GNU/Linux的发行版本&#xff0c;主要用做数字取证和入侵测试。其无线安全审…

BT5下载地址

http://www.backtrack-linux.org/downloads/ 下载方法&#xff1a; 1,先填写好网页里的三个框,如: Your Name(你的名字): ABC Email Address(邮箱): ABC163.com Country(国家): china 2,然后点"download" 3,按照自己的…

最全BT介绍

BitTorrent 简介 riba2534 2021年04月11日 19:26 阅读 851 关注 BitTorrent 简介 从 P2P 说起 经常在网上飙车的老司机应该都知道 BT 下载&#xff0c;但是有时候拿到了种子却下载不动&#xff0c;会不会很抓狂&#xff0c;是不是还觉得是自己网不行&#xff0c;那作为一…

034_Unicode标准

1. Unicode标准 1.1. 由于ASCII字符集、ISO字符集、GBK字符集列出的字符集都有容量限制, 而且不兼容多语言环境, Unicode联盟开发了Unicode标准。 1.2. Unicode标准涵盖了世界上的所有字符、标点和符号。 1.3. 不论是何种平台、程序或语言, Unicode都能够进行文本数据的处理…

24.字符编码

1.字符编码 1.1简介 字符编码只与文本文件和字符串有关。 字符编码&#xff1a;记录人类字符与二进制数的对应关系。计算机只能识别二进制&#xff0c;但是通过字符编码可以展示出各式各样的语言字符。1.2发展过程 1.计算机是美国人发明的&#xff0c;为了能够让加计算机能够…

汉字编码

http://blog.csdn.net/zzidea/article/details/8497532 C语言编程&#xff0c;基本的类型有字符型&#xff0c;整数型&#xff0c;浮点型。这些类型是我们对事物进行描述所必不可少的东西。即基础&#xff0c;又非常核心。所以必须掌握。 一、 字符集 ASCII GB2…

《Qt5:键盘事件》

QKeyEvent类用来描述了一个键盘事件。常用的键盘事件有两种&#xff1a;按键按下和按键释放&#xff0c;一般按键按下事件用的多一点&#xff0c;下面为键盘按下和释放事件的声明&#xff1a; public:void keyPressEvent(QKeyEvent *event);void keyReleaseEvent(QKeyEvent *ev…

小伙 这样你就可以在Mac 中运行 Office 办公软件了

小伙 这样你就可以在Mac 中运行 Office 办公软件了 请参考以下步骤&#xff1a; 1、打开已经安装好的 CrossOver&#xff0c;点击“安装 Windows 应用程序”&#xff0c;在选择应用中的搜索框中输入“office”&#xff0c;接下来在下拉列表中会出现非常多的已经列出的相关软件&…

Unicode 编码表

正则查找: 中文文字中文符号表情符号... [^\x00-\xff] 其中 \x00-\xff 匹配 ASCII 代码中十六进制代码为 00-ff 的字符&#xff0c; 加个取反 ^ &#xff0c;则就表示表示匹配非单字节的字符&#xff0c;例如汉字&#xff0c;汉字符号等字符集。 中文文字&#xff08;简体繁体…

arduino学习笔记-库函数解析_LiquidCrystal_i2c使用说明以及lcd1602的驱动

LiquidCrystal_i2c是一个通过i2c驱动lcd显示屏的库函数&#xff0c;具体使用说明如下 i2c转接芯片的型号 PCA8574 arduino R3 A05 为 SCL A04 为 SDL 在头文件下要初始化对象 LiquidCrystal_I2C lcd(0x27,16,2); 对象名 lcd 可以任意&#xff0c;这关系到下面你使用方法…

Linux-Ubuntu系统 安装(重装)Mysql

一、检查服务器是否已有mysql &#xff08;如需自行下载jdbc相关包&#xff0c;例如mysql-connector等的有效网站&#xff1a;https://mvnrepository.com/artifact/mysql/mysql-connector-java/6.0.2&#xff09; 为确保后续没有权限错误&#xff0c;先切换到root用户权限&am…