哈夫曼编码(理解)

article/2025/9/24 17:36:41

基础理解

什么是哈夫曼树(Huffman Tree)

        给定N个带权值的叶子节点,如何构造出一个带权路径最小的二叉树?

在数据结构理论中,哈夫曼树又称为最优树,相关的知识点还有哈弗曼编码等。在正式介绍哈夫曼树之前,需要知道下面的知识点:

(1)节点路径

按照规定,将树中一个节点到另一个节点所经历的分支,称为节点路径,比如上图中节点A到节点E的路径为ABE。

(2)路径长度

根据上述“节点路径”的定义,将路径上的分支总数称为路径长度,比如上图中节点A到节点E的路径长度为2。

(3)节点的带权路径长度

根据上述“节点路径”和“路径长度”的定义,将从根节点到某节点的路径长度和节点权值的乘积,称为节点的带权路径长度。比如上图中节点A到节点D的路径长度为2,权值为8,则带权路径长度为2x8=16。

(4)树的带权路径长度

根据上述“节点的带权路径长度”的定义,将树中所有叶子节点的带权路径长度,称为树的带权路径长度。比如上图中,三个叶子节点C、D、E,对应的路径长度分别为1、2、2,对应的权值分别为4、8、3,则树的带权路径长度为:

将上述概念形式化,可以使用下面的公式进行计算:

其中了表示路径长度,w表示权值,n表示叶子节点个数。

什么是哈夫曼编码(Huffman Coding)

又称霍夫曼编码,是一种编码方式,可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。

哈夫曼编码,主要目的是根据使用频率来最大化节省字符(编码)的存储空间

简易的理解就是,假如我有A,B,C,D,E五个字符,出现的频率(即权值)分别为5,4,3,2,1,那么我们第一步先取两个最小权值作为左右子树构造一个新树,即取1,2构成新树,其结点为1+2=3,如图:

虚线为新生成的结点,第二步再把新生成的权值为3的结点放到剩下的集合中,所以集合变成{5,4,3,3},再根据第二步,取最小的两个权值构成新树,如图:

再依次建立哈夫曼树,如下图:

其中各个权值替换对应的字符即为下图:

所以各字符对应的编码为:A->11,B->10,C->00,D->011,E->010
霍夫曼编码是一种无前缀编码。解码时不会混淆。其主要应用在数据压缩,加密解密等场合。

如果考虑到进一步节省存储空间,就应该将出现概率大(占比多)的字符用尽量少的0-1进行编码,也就是更靠近根(节点少),这也就是最优二叉树-哈夫曼树。
为什么?-----> 权值大的在上层,权值小的在下层。满足出现频率高的 码长 短。

哈夫曼编码的带权路径权值:叶子节点的值 * 叶子节点的高度(根节点为0)

深入研究

1、什么是哈夫曼编码?

在数据传送时,信息表现为0和1的二进制形式。为了提高传输的速度,可以采用变长的编码方式,寻找更优的编码方式。同时,必须要保证编码不存在二义性(任意字符编码都不是其它字符编码的前缀)。

哈夫曼编码就是符合上述要求的编码方式,采用自底向上的形式构造哈夫曼树。按照字符的概率分配码长,实现平均码长最短的编码

2、如何进行哈夫曼编码?

使用需要传送的字符构造字符集C = {c1, c2, ... cn},并根据字符出现的频率构建概率集W = {w1, w2, ... wn}。哈夫曼编码的流程如下:

  • 将字符集C作为叶子节点;
  • 将频率集W作为叶子节点的权值;
  • 使用C和W构造哈夫曼树;
  • 对哈夫曼树的所有分支,左子树分支编码为0,右子树分支编码为1;

通过上述流程,即完成了哈夫曼编码。

3、哈夫曼编码的例子?

首先,设定字符集为C = {T1, T2, T3, T4},对应的频率集为W = {2, 3, 7, 5},可以构造出下面的哈夫曼树(参见前面3篇文章):

构造出哈夫曼树后,只需要将左子树分支编码为0,右子树分支编码为1,即可获得哈夫曼编码如下:

4、哈夫曼编码方式有哪些?

对叶子节点进行Huffman编码共有两种方式,第一种是从根节点访问到叶子节点,第二种是从叶子节点访问到根节点(叶子节点具有parent数据成员,可以访问到其父节点)。

5、哈夫曼编码整体流程是什么?

含有4个字符(叶子节点)时,需要进行n-1次合并完成哈夫曼树的合并:

经过n-1次合并后,生成n-1个新的节点,最后生成的节点为哈夫曼树的根节点:

(1)创建长度为2n-1的哈夫曼树数组,含有n个叶子节点

(2)创建长度为n的string数组,用于存放n个叶子节点的哈夫曼码

(3)从某叶子节点开始,不断寻找其父节点,直到寻找到根节点,并对此路径上每个分支进行编码,左孩子为0,右孩子为1

6、如何从叶子节点访问到根节点?

从任意叶子X节点(数组前n项中的某一项)开始,根据X的parent值(即X的父节点在数组中的位置)找到其父节点。

找到X的父节点后,根据父节点的left和right值判断X和父节点的关系。如果X是父节点的左子树,则编码为1;如果X是父节点的右子树,则编码为0

编码函数如下:

void HuffmanCode(Node *p, const int numLeafs, string *codes) {// p为节点数组的指针,codes为string数组的指针 // 用于存储每个节点的哈夫曼码// parent表示父节点位置int parent;// 每次对一个叶子节点进行编码// i表示当前叶子节点位置for (int i=0; i < numLeafs; i++) {// j表示当前节点位置,i是不能在下面循环中改变的// 使用j来记录节点的移动过程int j = i;// 当前节点的父节点位置parent = p[i].parent;// 从当前叶子节点p[i]开始,找到哈夫曼树的根节点// 循环结束条件是此时parent为0,即达到哈夫曼树的根节点while(parent != -1) {// 如果当前节点是父节点的左子树,则此分支编码为0if (p[parent].left == j) {codes[i].push_back('0');}// 如果当前节点是父节点的右子树,则编码为1else {codes[i].push_back('1');}j = parent;parent = p[j].parent;}cout << codes[i] << endl;}
}


http://chatgpt.dhexx.cn/article/2RLscchs.shtml

相关文章

学弟学妹们,学会霍夫曼编码后,再也不用担心网络带宽了!

CSDN 的学弟学妹们&#xff0c;大家好&#xff0c;我是沉默王二。 今天来给大家普及一下霍夫曼编码&#xff08;Huffman Coding&#xff09;&#xff0c;一种用于无损数据压缩的熵编码算法&#xff0c;由美国计算机科学家大卫霍夫曼在 1952 年提出——这么专业的解释&#xff…

哈夫曼编码详解

一&#xff1a;基本介绍 哈夫曼编码也翻译为 赫夫曼编码(Huffman Coding)&#xff0c;又称霍夫曼编码&#xff0c;是一种编码方式, 属于一种程序算法 赫夫曼编码是赫哈夫曼树在电讯通信中的经典的应用之一。 赫夫曼编码广泛地用于数据文件压缩。其压缩率通常在20%&#xff5…

赫夫曼编码

一 基本介绍 1 赫夫曼编码也翻译为哈夫曼编码(Huffman Coding)&#xff0c;又称霍夫曼编码&#xff0c;是一种编码方式, 属于一种程序算法。 2 赫夫曼编码是赫哈夫曼树在电讯通信中的经典的应用之一。 3 赫夫曼编码广泛地用于数据文件压缩。 其压缩率通常在20%&#xff5e;9…

哈夫曼编码(Huffman Coding)原理详解

哈夫曼编码 哈夫曼编码&#xff0c;又称为哈夫曼编码&#xff08;Huffman Coding&#xff09; 是一种可变长编码&#xff08; VLC, variable length coding)&#xff09;方式&#xff0c;比起定长编码的 ASCII 编码来说&#xff0c;哈夫曼编码能节省很多的空间&#xff0c;因…

霍夫曼编码详解

本专栏包含信息论与编码的核心知识&#xff0c;按知识点组织&#xff0c;可作为教学或学习的参考。markdown版本已归档至【Github仓库&#xff1a;information-theory】&#xff0c;需要的朋友们自取。或者公众号【AIShareLab】回复 信息论 也可获取。 文章目录 霍夫曼编码最佳…

霍夫曼编码(Huffman Coding)

霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种。 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用…

Typecho 博客美化

以前用typecho博客&#xff0c;现在学生服务器到期了&#xff0c;先记录到csdn上&#xff0c;以后工作有钱了&#xff0c;再租个服务器写博客:) 代码高亮 https://www.typechodev.com/plugin/482.html 天气功能 使用心知天气带的插件就可以轻松实现了。 https://www.seniverse…

Hexo博客之博客美化

https://lqgjava.github.io/2019/08/24/Hexo博客之博客美化/ 只需阅读这一篇文章&#xff0c;就可以让你的博客变得丰富多彩&#xff0c;有添加卡通人物&#xff0c;添加鼠标点击爱心&#xff0c;添加鼠标指针样式 添加彩色滚动变换、添加背景音乐、添加动态彩带等&#xff0…

CSDN博客美化

排列博客分类 管理博客-分类专栏下修改 双击分类名称&#xff0c;即可编辑&#xff0c;输入“#”“空格”“分类名称”可将一级分类改成二级分类。 显示的效果 分类图标设置 编辑-设置图标&#xff0c;可以这里找阿里素材库 效果图

【CSDN】CSDN博客美化教程

一、效果 二、MarkDown简明教程 MarkDown简明教程 三、摘要 添加摘要&#xff0c;增加可读性。 PS. 其实&#xff0c;可以根据深度学习算法&#xff0c;自动生成摘要。 四、自定义博客栏目 五、修改皮肤

博客美化作业详细教程

博客美化作业 第一步 下载作业资源 第二步 在文件夹内打开下载资源 单击后缀为HTML文件的网页文件&#xff0c;右击用编译器打开 这些软件都可以&#xff08;除了紫色的&#xff09; 第三步 准备工作 首先让我们重新看下作业要求&#xff1a; 必须使用“类选择器”来美化网…

【全网最全的博客美化系列教程】04.访客量统计的实现

全网最全的博客美化系列教程相关文章目录 【全网最全的博客美化系列教程】01.添加Github项目链接 【全网最全的博客美化系列教程】02.添加QQ交谈链接 【全网最全的博客美化系列教程】03.给博客添加一只萌萌哒的小仓鼠 【全网最全的博客美化系列教程】04.访客量统计的实现 【全网…

Hexo博客美化之——IP签名图一网打尽

love421个人博客地址&#xff1a;https://www.makedreamsir.xyz IP签名图可以实时显示来访者的坐标&#xff0c;IP地址&#xff0c;操作系统&#xff0c;浏览器等等。 使用方法&#xff1a;将下面生成的链接插入到合适的位置即可。 项目原地址&#xff1a;点我打开 原作者博…

Web前端:博客美化:一、模板美化

1、选用模板simplememory 2、写css放在 这些会覆盖掉原来的css样式 我是在网上找的css代码二次加工的 : &#xff09; /*1、针对simplememory的修改*/ #google_ad_c1, #google_ad_c2 {display:none;} .syntaxhighlighter a, .syntaxhighlighter div, .syntaxhighlighter code, …

Hexo博客之主题美化

据说 NexT 是使用最多的Hexo主题,原因当然是比较漂亮啦!这个项目托管于github上,你可以fork一下,贡献代码。NexT官网上面给出了详细的主题配置过程,这里只是我的博客使用的一些配置以及NexT网站上配置中需要补充的部分。如果你是从头开始配置,请参考NexT官网。这篇文章介…

csdn写博客美化代码显示

本人写博客只是随笔记录&#xff0c;并不是很正规&#xff0c;见谅。 最近在写博客的时候发现自己贴的代码块就只显示代码&#xff0c;而一些前辈的代码块是这样的&#xff1a; 上图只看格式&#xff0c;代码无实际意义。 下面是我的代码块&#xff1a; 我写的代码块就…

【学习之博客美化】matery主题

为了方便我们这里使用 "Visual Studio Code"打开文件 将博客改为中文 目录&#xff1a;E:\IsQiyaBlog 将 " _config.yml " 文件中代码段 language: en 改为 language: zh-CN 修改主题菜单栏 将它们填上内容 新建分类 categories 页&#xff1a; hexo …

Hexo博客美化之蝴蝶(butterfly)主题魔改

这里写自定义目录标题 首先下载主题配置博客主题_config.yaml配置前须知_config.yaml配置简单介绍 如果参考我的脚手架&#xff0c;大家可以阅读readme和changelog文件&#xff0c;和蝴蝶主题官方文档。 tip: 由于butterfly主题升级至3.0.1&#xff0c;所提供的源码不在进行维护…

Vuepress博客美化技巧

文章目录 导航栏透明背景图填充跳转样式悬浮气泡背景图填充导航栏透明图片中的点击向下跳转的样式悬浮气泡 导航栏透明背景图填充跳转样式悬浮气泡 背景图填充 效果图&#xff1a; 下面的小框扩展到大框&#xff0c;让后面的导航栏透明更完善一些。 编辑Theme/components/Ho…

个人博客美化界面

先看一下我的界面 进入个人博客———管理——设置 在CSS代码框中输入一段代码&#xff0c;如下&#xff1a; /*simplememory*/ #google_ad_c1, #google_ad_c2 {display:none;} .syntaxhighlighter a, .syntaxhighlighter div, .syntaxhighlighter code, .syntaxhighlighter t…