【数据结构】哈夫曼树和哈夫曼编码

news2024/11/15 13:45:35

一、哈夫曼树

1.1 哈夫曼树的概念

给定一个序列,将序列中的所有元素作为叶子节点构建一棵二叉树,并使这棵树的带权路径长度最小,那么我们就得到了一棵哈夫曼树(又称最优二叉树)

接下来是名词解释:

  • 权:节点的数值
  • 路径长度:两节点间路径的边数
  • 带权路径长度:节点的权值乘以该节点到根节点的路径长度即为该节点的带权路径长度。哈夫曼树的带权路径长度是树中所有叶子节点的带权路径长度之和。

例如下面这棵哈夫曼树:

通过观察我们可以发现,所有父节点的权值都是自身的两个子节点的权值之和。而为了要使树的带权路径长度最小,我们要尽可能的让权值小的节点离根节点远,让权值大的节点离根节点近

因此,我们引出哈夫曼树的构造算法。

1.2 哈夫曼树的构造算法

要将一个序列构造成一棵哈夫曼树,我们首先需要对其进行升序排序

将排序好后的序列中的每个值看作一棵只有一个节点的树,从中选出根节点权值最小的两棵树作为新树的左右子树,并将这两棵树从序列中删除,而新树的根节点的权值是这两棵树根节点的权值之和

哈夫曼树没有规定左右子树的顺序,因此下面的例子中将10和18的位置对调也是正确的

将新树的根节点的权值放入序列中并重新进行升序排序,重复上述步骤

至此,就构建了一棵哈夫曼树

因为哈夫曼树没有规定左右子树的顺序,因此一个序列可以构建出不同的哈夫曼树

二、哈夫曼编码

2.1 等长编码

假设我们要对一个字符串ABAACDC进行二进制编码

我们可以按顺序给每个字符设置一个编码,A为0,B为1,C为10,D为11

那么就可以将上面的字符串转化为0100101110

但是在解码的时候我们会发现,这一串二进制序列可以解码为ACACDBA、ACABABDA等字符串,出现了歧义。

这是因为我们在对字符进行编码的时候,出现了一个字符是另一个字符的前缀的情况,例如D可以用两个B来表示。

为了避免歧义,我们可以采用等长编码的方案,就是每个字符的编码都一样长,例如A为00,B为01,C为10,D为11,这样就不会产生歧义了。

但是这种方案并不是一个最短的方案。

2.2 哈夫曼编码

统计字符出现的次数,把字符定义成一个节点,节点的权值就是它出现的次数。

例如上面A出现了3次,B出现了1次,C出现了2次,D出现了1次

哈夫曼编码的核心思想就是让出现次数越多的字符编出来的码越短,我们将全部节点构建成一棵哈夫曼树,出现次数越少的字符对应的节点就越靠近树的底层,编码也就越长,出现次数越多的字符编码就越短。

对二叉树的边标号,向左的边标为0,向右的边标为1,至此所有字符的编码就是从根节点到该字符节点路径上经过的标号,例如A为1,B为010,C为00,D为011,这种编码方案就叫做哈夫曼编码。

构建哈夫曼树的时候,所有的字符节点都是叶子节点,不会出现一个字符出现在另一个字符的路径上,也就不会出现一个字符是另一个字符的前缀这种造成歧义的情况

哈夫曼树的编码不是唯一的,节点放置的左右也会造成字符编码的不同,但是生成的编码长度一定都是一样的。

完.

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

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

相关文章

APISIX-简单使用

APISIX-简单使用 这个工具还是很不错的,可视化的配置很清晰 , 想用NGINX的配置模式也是可以的,就是要去修改配置文件了。 APISIX,一个很不错的可视化工具,用来代替Nginx相当不错,可作为Nginx的平替方案&…

Leecode热题100---45:跳跃游戏②

题目: 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。 返回到达 nums[n - 1] 的最小跳跃次数。 思路: 如果某一个作为 起跳点 的格子可以跳跃的距离是 3,那么表示后面…

解耦:哪些方法可以用来解耦代码

目录 1.引用 2.为何解耦如此重要 3.如何判断代码是否需要解耦 4.如何给代码解耦 5.思考题 1.引用 前面我们曾经讲到,重构可以分为大型重构和小型重构。小型重构的主要目的是提高代码的可读性,大型重构的主要目的是解耦。本节讲解如何对代码进行解耦…

用python为目录下的文件生成索引

好久没写文章了。 有一个需求: 我的一个目录下有很多的.html文件, 每个html会包含一些image ,但都在各自的目录中。 .html特别多,有好几百个,我需要一个index.hmtl把这些html全部索引起来,使得我一个点击&a…

计算机如何将输入文字显示出来的?渲染Image rendering

1.文字渲染的简单理解 渲染图像,可以理解为用cpu/gpu构造出原本不存在的图像。比如输入计算机的英文字符都是ASCII码,而我们在屏幕上看到显示的字符对应的应该是RGB/YUV的像素。计算机把ASCII字符转化成像素的过程就是文字渲染。又比如我们GPU用多个2D图…

全同态加密生态项目盘点:FHE技术的崛起以及应用

撰文:Chris,Techub News 在当今数字化的时代,隐私保护已成为一个全球性的焦点话题,特别是在加密货币和区块链技术快速发展的背景下。虽然当前的隐私技术在保护数据安全方面多有欠缺,引发了广泛的关注和批评&#xff0c…

如何彻底搞懂装饰器(Decorator)设计模式?

对于任何一个软件系统而言,往现有对象中添加新功能是一种不可避免的实现场景,但这一实现过程对现有系统的影响可大可小。从架构设计上讲,我们也知道存在一个开闭原则(Open-Closed Principle,OCP)&#xff0…

中文信息期刊投稿邮箱

《中文信息》杂志是国家新闻出版总署批准的国家级刊物(月刊),国内外公开发行,大十六开印刷。本刊主要反映我国中文信息处理的学术水平,重点刊登科技、经济、教育等领域的基础理论、科研与应用技术的学术论文&#xff0…

使用Coding部署项目

coding概述:提供一站式开发协作工具,帮助研发团队快速落地敏捷开发与 DevOps 开发方式,实现研发效能升级 一、创建项目 省略 详细文档:https://g-mnbk6665.coding.net/quickstart 二、SSH连接 关于ssh相关命令 重启SSH服务 s…

2023蓝桥杯大赛软件类省赛Java大学B组G题 买二增一 队列的简单应用

用队列 Queue package Dduo; //Bhu Bigdata 1421 //Eslipse IDE 2020-08 //JDK 1.8 //2024/5/19 import java.util.Scanner; import java.math.BigInteger; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue;public class Main {public static v…

【openlayers系统学习】1.6下载要素,将要素数据序列化为 GeoJSON并下载

六、下载要素 下载要素 上传数据并编辑后&#xff0c;我们想让用户下载结果。为此&#xff0c;我们将要素数据序列化为 GeoJSON&#xff0c;并创建一个带有 download​ 属性的 <a>​ 元素&#xff0c;该属性会触发浏览器的文件保存对话框。同时&#xff0c;我们将在地图…

二叉树顺序结构及链式结构

一.二叉树的顺序结构 1.定义&#xff1a;使用数组存储数据&#xff0c;一般使用数组只适合表示完全二叉树&#xff0c;此时不会有空间的浪费 注&#xff1a;二叉树的顺序存储在逻辑上是一颗二叉树&#xff0c;但是在物理上是一个数组&#xff0c;此时需要程序员自己想清楚调整…

GPT-4o: 未来的智能助手

GPT-4o: 未来的智能助手 在这个信息爆炸的时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为我们生活中不可或缺的一部分。作为OpenAI最新推出的语言模型&#xff0c;GPT-4o不仅继承了前几代模型的优点&#xff0c;还在多个方面进行了显著的提升。本文将带你深入了解…

C++:vector基础讲解

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《C&#xff1a;vector基础讲解》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 如果本篇文章对你有帮助&#xff0c;还请各位点点赞&#xff01;&#…

网络编程day7

思维导图 数据库编程实现学生管理系统 #include <header.h> #define ID 1 #define NAME 2 #define AGE 3 #define SCORE 4 int do_add(sqlite3 *ppdb) {int add_numb;char add_name[20];int add_age;double add_score;printf("enter student id:");scanf(&quo…

1076: 判断给定有向图是否存在回路

解法&#xff1a; 直观的方法用邻接矩阵dfs,这是错误的代码 #include<iostream> #include<vector> using namespace std; int arr[100][100]; int f 0; void dfs(vector<int>& a, int u) {a[u] 1;for (int i 0; i < a.size(); i) {if (arr[u][i]…

绝缘监测系统在1kV 及以下低压配电系统的应用

安科瑞电气股份有限公司 祁洁 acrelqj 一、系统概述 Acrel-2000L/A 绝缘监测系统设备适用于 1kV 及以下低压配电系统。该设备可以集中采集监测显示绝缘监测仪的数据&#xff0c;实现最多 8 个绝缘监测仪的数据&#xff0c;并且实时记录告警信息和曲线查询。匹配的绝缘监测仪…

bootstrap入门

官方网站&#xff1a;全局 CSS 样式 Bootstrap v3 中文文档 | Bootstrap 中文网 里面各种可以直接用的组件 不全的话可以网上搜索Boostrap常用的按钮样式_btn-large-dim-CSDN博客 怎么在vue项目中使用呢 npm install bootstrap 下载下来然后在main.js加上红框三句后&#…

SpringCloudAlibaba:6.2RocketMQ的普通消息的使用

简介 普通消息也叫并发消息&#xff0c;是发送效率最高&#xff0c;使用最多的一种 依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSch…

1701java药品进销存管理系统Myeclipse开发sqlserver数据库web结构java编程计算机网页项目

一、源码特点 java web药品进销存管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境 为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为s…