数据结构学习记录——哈夫曼树(什么是哈夫曼树、哈夫曼树的定义、哈夫曼树的构造、哈夫曼树的特点、哈夫曼编码)

news2024/9/21 21:20:42

目录

什么是哈夫曼树

哈夫曼树的定义

哈夫曼树的构造 

图解操作

代码实现

代码解析

哈夫曼树的特点

哈夫曼编码 

不等长编码

二叉树用于编码

哈夫曼编码实例 


什么是哈夫曼树

我们先举个例子:

要将百分制的考试成绩转化成五分制的成绩

if(score < 60)
    grade = 1;
else if(score < 70)
    grade = 2;
else if(score < 80)
    grade = 3;
else if(score < 90)
    grade = 4;
else
    grade = 5;

这种情况其实是一棵判定树:

这种方式要看各成绩段的学生分布,如果60以下的同学比较多,那么判断的次数就会很少;但是如果90多的同学比较多的情况下,那么要判断4次的情况就会很多,整体的判断效率不高。

我们考虑学生成绩分布的概率:

分数段0-5960-6970-7980-8990-100
比例0.050.150.400.300.10

那么判断效率就为:0.05\times 1+0.15\times 2+0.40\times 3+0.30\times 4+0.10\times 4 =\mathbf{3.15}

现在我们想要让判断的效率更高一点,修改一下判定树:

这样的判断效率就为:0.05\times 3+0.15\times 3+0.4\times 2+0.3\times 2+0.1\times 2 = \textbf{​{\color{Red} 2.2}} 

写成代码就为:

if(score < 80)
{
    if(score < 70)
    {
        if(score < 60)
        {
            grade = 1;
        }
        else
        {
            grade = 2;
        }
    }
    else
    {
        grade = 3;
    }
}
else if(score < 90)
{
    grade = 4;
}
else
{   
    grade = 5;
}

如何根据结点不同的查找频率构造更有效的搜索树? 

就涉及到了我们要讲的哈夫曼树

哈夫曼树的定义

带权路径长度(WPL):设二叉树有n个叶子结点,每个叶子结点带有权值w_{k},从根结点到每个叶子结点的长度为l_{k},则每个叶子结点的带权路径长度之和就为:WPL = \sum_{k = 1}^{n}w_{k}l_{k}

最优二叉树哈夫曼树WPL最小的二叉树。

例:有五个叶子结点,它们的权值为{1,2,3,4,5},用此权值序列可以构造出形状不同的多个二叉树。

哈夫曼树的构造 

给出一个权值序列,构造出一棵哈夫曼树。

例:{1,2,3,4,5}

每次把权值最小的两棵二叉树合并,具体:

图解操作

哈夫曼树的构造是比较简单的,要找出两个最小值,就可以运用我们前面学过的最小堆来找了,这比从小到大排好序的效率会更高。下面我们来看一下代码的实现。

代码实现

typedef struct TreeNode *HuffmanTree;
struct TreeNode
{
    int Weight;
    HuffmanTree Left,Right;
}

HuffmanTree Huffman(MinHeap H)
{    /*假设H->Size个权值已经存在H->Elements[]->Weight里*/
    int i;
    HuffmanTree T;
    BuildMinHeap(H);/*将H->Elements[]按权值调整为最小堆*/
    for (i=1;i<H->Size;i++)
    {
        /*做H->Size-1次合并*/
        T=malloc( sizeof( struct TreeNode));/*建立新结点*/ 
        T->Left=DeleteMin(H);
        /*从最小堆中删除一个结点,作为新T的左子结点*/
        T->Riqht=DeleteMin(H);
        /*从最小堆中删除一个结点,作为新T的右子结点*/
        T->Weight=T->Left->Weiqht + T->Right->Weight;
            /*计算新权值*/
        Insert(H,T);/*将新T插入最小堆*/
    }
    T=DeleteMin(H);
    return T;  
}

代码解析

这段代码定义了一个结构体类型TreeNode和一个指向TreeNode类型的指针HuffmanTree。TreeNode结构体包含三个成员变量:Weight表示权值,Left表示左子树指针,Right表示右子树指针。

HuffmanTree指针类型可以指向TreeNode类型的对象,用于表示哈夫曼树的结点。

函数的输入参数是一个最小堆H,其中存储了每个字符出现的频率。

变量 i 的作用是用于循环合并最小堆中的结点,每次循环合并两个权值最小的结点,直到只剩下一个根结点。

T的作用是用于创建新的Huffman树结点,每次合并两个最小权值的结点时,都会创建一个新的结点T,并将两个最小权值结点作为T的左右子结点,然后将T插入到最小堆中。

最终,最小堆中只剩下一个根结点,即为Huffman树的根结点,返回该结点即可。

函数首先调用BuildMinHeap函数将H中的元素按照权值调整为最小堆。

然后进入for循环,将最小堆中的所有结点合并成一棵哈夫曼树:

首先,建立一个新的结点T,作为合并后的新结点。

然后,从最小堆中删除两个权值最小的结点,分别作为新结点T的左子结点和右子结点。

接着,计算新结点T的权值,即左子结点和右子结点的权值之和。

最后,将新结点T插入最小堆中。

这个过程会重复执行H->Size-1次,因为最终的哈夫曼树只有一个根结点,所以需要将所有结点合并成一个。

最后,从最小堆中删除最后一个结点,即哈夫曼树的根结点,

并返回该结点作为哈夫曼树的根。

哈夫曼树构造完成。整体的时间复杂度为O(N{log_{2}}^{N})

哈夫曼树的特点

  • 没有度为1的结点

哈夫曼树是一棵最优二叉树,每个叶子结点都对应着一个字符,

而每个非叶子结点都是两个子结点的父结点,表示两个字符的合并。

如果存在度为1的结点,那么这个结点只有一个子结点,就不能表示两个字符的合并,因此不符合哈夫曼树的定义。

  • n个叶子结点的哈夫曼树共有2n-1个结点

我们最开始学二叉树时,在其中提到了二叉树的几个重要性质。

对任何非空二叉树T,若n0表示叶节点的个数,n2是度为2的非叶节点个数,那么两者满足关系n0 = n2 +1

因为哈夫曼树没有度为1的结点,叶结点为n个,那么度为2的非叶结点个数就为n-1个;

故而总结点数就等于n + (n - 1) = 2n - 1

  • 哈夫曼树的任意非叶结点的左右子树交换之后仍是哈夫曼树

交换哈夫曼树中任意非叶结点的左右子树时,它的深度和权值并没有发生改变,因此仍然满足哈夫曼树的定义。

  • 对同一组权值{w_{1},w_{2},......,w_{n}},存在不同构的两棵哈夫曼树

对一组权值{1,2,3,3},不同构的两棵哈夫曼树:

哈夫曼编码 

不等长编码

抛出问题:给定一段字符串,如何对字符进行编码,可以使得该字符串的编码存储空间最少

【例】假设有一段文本,包含58个字符,并由以下7个字符构成:a,e,i,s,t,空格(sp),换行(nl);这7个字符出现的次数不同。如何对这7个字符进行编码,使得总编码空间最少?

【分析】

(1)用等长ASCII编码(ASCII占1个字节,8个比特位):58 * 8 = 464位;

(2)用等长3位编码(因为只有7个字符,3位的编码足够表达8个对象):58 * 3 = 174位;

(3)不等长编码:出现频率高的字符用的编码短些,出现频率低的字符则可以编码长些

怎么进行不等长编码呢?

我们不妨假设:

a:0

e:0

s:10

t:11

......

那么在这样的不等长编码下,1011是什么字符串的编码?

a e a a1 0 1 1

a e t:1 0 1 1

s t:1 0 1 1

这样就出现了同一个编码,却译出不同的几个字符串了,即存在二义性

要避免二义性,就要满足一个条件:前缀码

前缀码prefix code:任何字符的编码都不是另一字符编码的前缀

例如,s的前缀为1,而1就可以理解为a,这就不符合前缀码的条件了。

二叉树用于编码

为了保证我们的编码不出现二义性,我们可以用二叉树来编码。

用二叉树编码:

(1)左分支:0

(2)右分支:1

(3)字符只在叶结点上

【例】现有四个字符的频率:a:4,u:1,x:2,z:1。

前面说过的前缀码,是当字符出现在叶结点时;如果字符出现在非叶结点上,就说明它不满足前缀码的条件:

 所以这就是为什么用二叉树来编码时,字符只在叶结点上。

接下来的问题是,怎么样构造才能使得付出的代价最小?

看到刚才举的例子: 

这就和我们讲哈夫曼树时是差不多的情况,我们根据频率来把二叉树重构一下: 

这样不存在二义性,代价也最小。

哈夫曼编码实例 

【例】

C_{i}aeistspnl
f_{i}10151234131

用上面学过的构造哈夫曼树的方法,每次选取最小的两个值构造二叉树,整个过程如下

 最终构造出来的哈夫曼编码树:


end 


学习自:MOOC数据结构——陈越、何钦铭 

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

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

相关文章

ASEMI代理ADV7391BCPZ原装ADI车规级ADV7391BCPZ

编辑&#xff1a;ll ASEMI代理ADV7391BCPZ原装ADI车规级ADV7391BCPZ 型号&#xff1a;ADV7391BCPZ 品牌&#xff1a;ADI /亚德诺 封装&#xff1a;LFCSP-32 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 引脚数量&#xff1a;32 工作温度:-40C~85C 类型&…

ChatGPT实现markdown 格式与 emoji 表情

markdown 格式与 emoji 表情 书写文章时&#xff0c;巧妙的使用一些小图标&#xff0c;可以给文章增加不少的灵动感&#xff0c;读者也会感觉更加轻松。恰当的图标也能增进读者对内容的理解。ChatGPT 目前不能直接联网&#xff0c;但可以使用 emoji 表情文字来达到类似的效果。…

笔记本电脑开机黑屏没反应怎么办?

笔记本电脑开机黑屏没反应怎么办&#xff1f;有用户电脑开机之后&#xff0c;桌面会变成黑屏显示。而且是常常都会出现这样的问题&#xff0c;非常影响自己的电脑使用体验。那么遇到这个问题要怎么去进行问题的解决呢&#xff1f;来看看以下的解决方法吧。 准备工作&#xff1a…

超级详细的mysql数据库安装指南

MySql数据库 如果你的电脑是mac那么你看这位大佬的分享。 如果你的电脑是windows&#xff0c;参考下面的安装步骤。 一、下载mysql数据库&#xff1f; 进入MySQL官方网站&#xff08;MySQL Community Downloads&#xff09;&#xff0c;按下图顺序点击 1、进入下载页面 2、…

Dom树,什么是dom树?

相信很多初学前端的小伙伴&#xff0c;学了html, css, js之后&#xff0c;会遇到 一个名词 DOM树。 首先说一下DOM是什么&#xff1f; DOM 是 Document Object Model&#xff08;文档对象模型&#xff09;的缩写。 举个例子 我们日常生活中&#xff0c;经常会遇到一些写文档…

Spring Cloud第二季--消息驱动Spring Cloud Stream

文章目录 什么是Spring Cloud StreamStream 原理 牛刀小试消息重复消费问题 什么是Spring Cloud Stream Spring Cloud Stream is a framework for building highly scalable event-driven microservices connected with shared messaging systems. The framework provides a fl…

linux系统函数的运用

函数 函数详解函数的作用函数的定义函数的返回值函数的作用范围函数传参函数递归函数库 函数详解 函数的作用 在编写shell脚本的时候&#xff0c;经常会发现在多个地方使用了同一段代码&#xff0c;如果只是一小段代码&#xff0c;一般也无关紧要&#xff0c;但是要在脚本中多…

如何禁止电脑运行游戏?

在休息的时候&#xff0c;很多人都喜欢使用电脑玩游戏来消磨时间&#xff0c;但是对于未成年人来说&#xff0c;很容易沉迷游戏&#xff0c;从而影响正常的学业和成长。那么如何才能禁止电脑运行游戏呢&#xff1f;下面我们就来了解一下。 除了将电脑游戏卸载之外&#xff0c;还…

markdown甘特图语法介绍

1. 介绍 甘特图&#xff08;Gantt chart&#xff09;又称为横道图、条状图(Bar chart)。其通过条状图来显示项目、进度和其他时间相关的系统进展的内在关系随着时间进展的情况。 2. 语法 1. 代码通用语法 在 markdown 的 代码模块 中编写甘特图&#xff0c;类型是mermaid&a…

华硕ROG|玩家国度魔霸新锐2023 Windows11原厂预装系统 工厂模式恢复安装带ASUSRecevory一键还原

华硕ROG|玩家国度魔霸新锐2023 Windows11原厂预装系统 工厂模式恢复安装带ASUSRecevory一键还原 文件地址&#xff1a;https://pan.baidu.com/s/1snKOsH3OMl3GZLqeAf-GLA?pwd8888 华硕工厂恢复系统 &#xff0c;安装结束后带隐藏分区以及机器所有驱动软件 需准备一个16G左右…

第三十二章 React路由组件的简单使用

1、NavLink的使用 一个特殊版本的 Link&#xff0c;当它与当前 URL 匹配时&#xff0c;为其渲染元素添加样式属性 <NavLink className"list-group-item" to"/home">Home</NavLink> <NavLink className"list-group-item" to&quo…

Python 密码破解指南:0~4

协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【OpenDocCN 饱和式翻译计划】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 收割 SB 的人会被 SB 们封神&#xff0c;试图唤醒 SB 的人是 SB 眼中的 SB。——SB 第三定律 零、简…

stream笔记

1、 创建流stream 1.1、 Stream 的操作三个步骤 1.2、 stream中间操作 1.2.1 、 limit、skip、distinct 1.2.2、 map and flatMap 1.2.3、 sort 自然排序和定制排序 1.3、 add and andAll difference: 1.4、 终止操作 1.4.1、 allmatch、anyMatch、noneMatch、max、min…

JavaScript通过js的方式来判断一个数奇偶性的代码

以下为通过js的方式来判断一个数奇偶性的程序代码和运行截图 目录 前言 一、通过js的方式来判断一个数奇偶性&#xff08;html部分&#xff09; 1.1 运行流程及思想 1.2 代码段 二、通过js的方式来判断一个数奇偶性&#xff08;js部分&#xff09; 2.1 运行流程及思想 2…

美国新的 AI 研究基金将专注于 6 个领域

美国白宫周四宣布&#xff0c;在 1.4 亿美元的联邦资金支持下&#xff0c;拜登政府将开设七个新的人工智能实验室。 国家科学基金会将在其他政府机构的支持下掌舵运营。这些研究所将专注于六个研究课题&#xff1a; 1. 值得信赖的人工智能&#xff0c;隶属于马里兰大学领导的…

JustFE团队前端代码规范,降本增效,敏感肌可用

背景 &#x1f30f; 近年来&#xff0c;接手各个前端的代码&#xff0c;看着前人屎山&#xff0c;深恶痛绝 为了避免自己或者团队&#xff0c;继续添粪&#xff0c;因此经验总结一番~ 规范化优点&#xff1a; 容易理解&#xff0c;维护性强容易编写&#xff0c;扩展性强精准定…

优化营商环境:打造政策精准服务平台,提高惠政策落实落地时效性

近年来&#xff0c;各级政府部门及产业园区不断加强对于惠企政策的宣传和落实&#xff0c;努力打造优质的营商环境&#xff0c;加大助企纾困力度&#xff0c;以推动经济高质量发展。为了更好地实现这一目标&#xff0c;搭建惠企政策精准服务平台成为了一个非常重要的举措。 搭建…

Apache Zeppelin系列教程第四篇——Interpreter原理分析

Interpreter 其实就是整个项目的核心&#xff0c;代码运行都是在里面进行执行的&#xff0c;首先来看下Interpreter的抽象类 以jdbc-Interpreter为例&#xff0c;可以参考下测试代码(这个代码里面可以直接测试jdbc的sql执行过程和数据返回过程) 参数和介绍可以参考官方文档&am…

CH9329双头线使用说明

1.介绍说明 CH9329双头线是集成了CH9329CH340芯片的成品线&#xff0c;主要作用是使用主控电脑发送串口指令数据来控制被控电脑的键盘以及鼠标的功能。主控电脑和被控电脑可以是同一台电脑&#xff0c;就是能够自己控制自己。支持自定义修改USB的硬件信息&#xff0c;如PID、V…

FTP-HTTP-HTTPS的学习总结

FTP协议的学习 一&#xff0c;学习的要点 ftp的掌握总体架构、了解状态机 请求响应的格式、常用操作码及响应的含义 PORT与PASV的区别、断点续传 上传、下载文件的基本流程 1&#xff0c;FTP的架构主要有两种形式 UserPI&#xff08;用户解释器&#xff09;和ServerPI&…