数据机构笔记哈夫曼编码

news2024/9/22 20:23:31

1.什么是哈夫曼树?

哈夫曼树经典问题:

合并果堆问题:

如果有三个果堆,其质量分别是1,2,3,我们现在需要将这三堆合并成一堆果堆,合并过程消耗体力等于两堆果堆的质量之和,求最小体力消耗值?

答:首先,不要以为无论怎么搭配消耗的体力是一样的

  1. 如果先13,得到一个4的果堆,消耗体力为4,再和2合并,42,得到一个6的果堆,消耗体力为6,总共消耗体力为(4+6) = 10。

  1. 如果是先12,则得到一个3的果堆,消耗体力为3,再和3合并,33,得到一个6的果堆,消耗体力为6,总共消耗体力为(3+6) = 9。

  1. 2+3 = 5, 5 + 1 = 6, (5+6) = 11。

综上所述, 2情况下的体力消耗值最小。

哈夫曼树就是为了解决该类问题而提出的

如何用哈夫曼树解决以上的问题?

让果堆作为叶子结点,权值为果堆的重量,那么非叶子结点就是合并出来的果堆的质量,也可以说是合并这次消耗的体力值,那么从根结点到叶子结点的和就是总共消耗的体力值,这样遍历所有到叶子结点的路径(非叶子结点之和)即可找出最小消耗体力值。

这样就可以画出三棵哈夫曼树:

由此可以看出一个问题的哈夫曼树不只有一颗,一颗哈夫曼树有唯一解,但这颗不一定是这个问题的最优解。

事实上,该哈夫曼树的解也可以通过求树的带权路径长度(weighted path length of tree)(WPL),带权路径长度就是步长*该结点的权值,它等于所有叶子结点的带权路径长度之和,步长即从根结点出发到达该结点所经过边数。

如1,就是(1*2)+(2*2)+(1*3) = 9,为所求。

//由上面三张图可知,哈夫曼树不唯一,但是最小带权路径长度唯一。

因此:

哈夫曼树就是最优二叉树,哈夫曼树用于求最小带权路径长度。(求多种配合方案的唯一最有解)

2.如何建立一颗哈夫曼树?

  1. n个结点,每个结点看作一棵树

  1. 当前根结点权值最小的两棵树两两合并//有点像贪心

  1. 重复2,直到只剩一棵树,这个树就是哈夫曼树。

以果堆问题为例:

使用优先队列(小顶堆)(priority_queue),每次从优先队列拿出两个最小权值,相加后再入队,重复直到只剩一个权值时结束,相加的时候再设置一个外部变量ans将相加结果记录,最后ans的值即为树的最小路径长度。

(相加结果的反复相加之和)

优先队列:队首元素一定是当前队列中优先级最高的那个一个。(默认从大到小)

如何用优先队列定义一个小顶堆:

priority_queue<long long, vector<long long>, greater<long long>>q

//第一个是优先队列存储元素类型,第二个是实现堆使用的容器,第三个是优先级设置。

3.什么是哈夫曼编码?

为了方便数据传输,将字符串转换成01串的形式,设A:0 B:1 C:00 D:01

那么ABCAD就为0100001,我们发现前缀“01”既可能是AB也可能是D,产生了二意性,A的编码是D的前缀,那么有其他字符和A拼接就有可能产生D,因此这种做法是错误的。

原理就是利用哈夫曼编码,因为叶子结点的编码代表到叶子结点的路径,是唯一的。

//结点的前缀编码的长度等于步长,步长*权值 = 带权路径长度,因此字符串编码成01串后的长度实际上就是这棵树的带权路径长度。

//哈夫曼树的出现,可以使得前缀编码的长度最短,这个最短的前缀编码叫做哈夫曼编码。

(即如何根据字符出现的次数(质量)来设置一颗哈夫曼树,让其树的带权路径长度最小(体总力消耗))。

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

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

相关文章

java贪心算法

1 应用场景-集合覆盖问题 假设存在下面需要付费的广播台&#xff0c;以及广播台信号可以覆盖的地区。 如何选择最少的广播台&#xff0c;让所有的地区 都可以接收到信号 2 贪心算法介绍 贪婪算法(贪心算法)是指在对问题进行求解时&#xff0c;在每一步选择中都采取最好或者最优…

Threadlocal为何引发内存泄漏问题

首先我们要先了解什么是泄漏问题和什么是内存溢出 内存泄漏表示程序员申请了内存&#xff0c;但是该内存一直无法被释放 内存溢出表示申请内存不足&#xff0c;就会报错 为何引发内存泄漏问题 因为每个线程都有自己独立的ThreadLocalMap对象&#xff0c;key为ThreadLocal&…

【C++1】函数重载,类和对象,引用,string类,vector容器,类继承和多态,/socket,进程信号

文章目录1.函数重载&#xff1a;writetofile()&#xff0c;Ctrue和false&#xff0c;C0和非02.类和对象&#xff1a;vprintf2.1 构造函数&#xff1a;对成员变量初始化2.2 析构函数&#xff1a;一个类只有一个&#xff0c;不允许被重载3.引用&#xff1a;C中&取地址&#x…

【shell 编程大全】内容格式化以及多样化输出

内容格式化以及多样化输出 1. 前倾回顾 本章节我们一起来学习下&#xff0c;shell中内容格式化&#xff0c;以及多样输出。但是在学习之前&#xff0c;我们先来看看上个章节【shell 变量的定义以及使用】 我们都学习到了什么知识 shell 变量的定义以及使用 变量分类变量定义类…

SpringBoot设置和读取配置文件(1)

SpringBoot配置文件是用来保存SpringBoot项目当中所有重要的数据的&#xff0c;比如说数据库连接信息&#xff0c;数据库的启动端口&#xff0c;如果端口被占用了&#xff0c;那么就可以随时修改&#xff1b; 1)比如说我们之前再写JDBC的代码的时候&#xff0c;要去写链接字符串…

C 字符串

在 C 语言中&#xff0c;字符串实际上是使用空字符 \0 结尾的一维字符数组。因此&#xff0c;\0 是用于标记字符串的结束。空字符&#xff08;Null character&#xff09;又称结束符&#xff0c;缩写 NUL&#xff0c;是一个数值为 0 的控制字符&#xff0c;\0 是转义字符&#…

SNI生效条件 - 补充nginx-host绕过实例复现中SNI绕过的先决条件

文章目录1.前置环境搭建2.测试SNI生效条件(时间)3. 证书对SNI的影响3.1 双方使用同一个证书&#xff1a;3.2 双方使用不同的证书与私钥4. 端口号区分测试4.1 端口号区分&#xff0c;证书区分&#xff1a;4.2 端口号区分,证书不区分&#xff1a;5.总结SNI运行机制6. SNI机制绕过…

Docker-安装Jenkins-使用jenkins发版Java项目

文章目录0.前言环境背景1.操作流程1.1前期准备工作1.1.1环境变量的配置1.2使用流水线的方式进行发版1.2.1新建流水线任务1.2.2流水线操作工具tools步骤stages步骤1:拉取代码编译步骤2:发送文件并启动0.前言 学海无涯&#xff0c;旅“途”漫漫&#xff0c;“途”中小记&#xff…

从0到1一步一步玩转openEuler--12 openEuler用户管理

文章目录12.1 创建用户12.1.1 useradd命令12.1.2 用户信息文件12.1.3 创建用户实例12.2 修改用户账号12.2.1 修改密码12.2.2 修改用户shell设置12.2.3 修改主目录12.2.4 修改UID12.2.5 修改账号的有效期12.3 删除用户12.4 管理员账户授权在Linux中&#xff0c;每个普通用户都有…

【Java 面试合集】怎么声明一个类不会被继承,以及应用场景

怎么声明一个类不会被继承&#xff0c;以及应用场景1. 概述 今天的Java 面试合集又来了。今天我们复习的问题是:怎么声明一个类&#xff0c;不可以被继承 2. 验证 public final class TestMath { }通过上述截图 我们可以看到&#xff0c;被关键字final 修饰过的类&#xff0c;…

EOC第六章《块与中枢派发》

文章目录第37条&#xff1a;理解block这一概念第38条&#xff1a;为常用的块类型创建typedef第39条&#xff1a;用handler块降低代码分散程度第41条&#xff1a;多用派发队列&#xff0c;少用同步锁方案一&#xff1a;使用串行同步队列来将读写操作都安排到同一个队列里&#x…

02 OpenCV图像通道处理

1 通道提取与合并 在数字图像处理中&#xff0c;图像通道是指一个图像中的颜色信息被分离为不同的颜色分量。常见的图像通道包括RGB通道、灰度通道、HSV通道等。 RGB通道是指将图像分离为红色、绿色和蓝色三个颜色通道&#xff0c;每个通道表示相应颜色的亮度。这种方式是最常…

【QT 5 相关实验-仪表盘-学习笔记-表盘组件练习与使用总结】

【QT 5 相关实验-仪表盘-学习笔记-表盘组件练习与使用总结】1、概述2、实验环境3、参考资料-致谢4、自我提升实验效果5、代码练习-学习后拆解&#xff08;1&#xff09;头文件部分&#xff08;2&#xff09;绘制事件绘制表盘代码&#xff08;3) 每一块部分绘制6、代码移植提升类…

Spring Security in Action 第十一章 SpringSecurity前后端分离实战

本专栏将从基础开始&#xff0c;循序渐进&#xff0c;以实战为线索&#xff0c;逐步深入SpringSecurity相关知识相关知识&#xff0c;打造完整的SpringSecurity学习步骤&#xff0c;提升工程化编码能力和思维能力&#xff0c;写出高质量代码。希望大家都能够从中有所收获&#…

nginx正向代理的配置和使用

nginx正向代理的配置和使用 nginx正向代理的配置和使用nginx正向代理的配置和使用安装包准备下载nginx安装包下载正向代理模块的包版本与模块对照表部署nginx服务上传nginx包和正向模块包解压,改名安装nginx配置正向代理创建nginx用户检查nginx配置并启动nginx服务所在服务器验…

微服务02 Docker

Docker实用篇0.学习目标1.初识Docker1.1.什么是Docker微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署&#xff0…

实战绕过WTS-WAF的SQL注入

实战绕过WTS-WAF的SQL注入1.前言2.测试流程2.1.发现漏洞2.1.1.正常页面2.1.2.WAF警告2.1.3.非正常页面2.2.判断字段数2.2.1.非正常页面2.2.2.正常页面2.3.判断回显位2.4.信息收集2.4.1.数据库版本2.4.2.数据库名2.5.判断数据库表2.5.1.WAF告警2.5.2.获取表2.5.3.burp suite测试…

龙曲良 Tensorflow —— tensorflow高级操作(自用)

目录 一、合并与分割 1.1 tf.concat (合并) 1.2 tf.stack &#xff08;增加新维度&#xff09; 1.3 tf.unstack &#xff08;一个一个拆分&#xff09; 1.4 tf.split &#xff08;均分拆分&#xff09; 二、数据统计 2.1 tf.norm&#xff08;默认二范数&#xff09; 2…

WebRTC(一):三种架构和基本原理

文章目录一、三种架构二、为什么SFU最为常用&#xff1f;一、三种架构 webrtc大致可以分为三种架构&#xff1a; MESH mesh架构需要所有参与连接的peer简历和所有其他peer的媒体的连接&#xff0c;如图一。 该架构需要n-1个上下行&#xff0c;以此带来的带宽消耗&#xff08…

家政服务小程序实战教程02-创建模型应用

我们在上一篇中介绍了数据源的设计及创建方法&#xff0c;本篇我们就根据我们创建好的数据源来设计功能。 按我们的需求分析&#xff0c;系统管理员来审核数据&#xff0c;要想审核数据需要给管理员提供一个管理后台。微搭中的管理后台是通过模型应用来解决的。 登录控制台&a…