[入门必看]数据结构5.5:树与二叉树的应用

news2024/9/20 6:44:05

[入门必看]数据结构5.5:树与二叉树的应用

  • 第五章 树与二叉树
  • 5.5 树与二叉树的应用
    • 知识总览
      • 5.5.1 哈夫曼树
      • 5.5.2_1 并查集
      • 5.5.2_2 并查集的进一步优化
    • 5.5.1 哈夫曼树
      • 带权路径长度
      • 哈夫曼树的定义
      • 哈夫曼树的构造
      • 哈夫曼编码
      • 应用:英文字母频次
    • 5.5.2_1 并查集
      • 漏网之鱼:逻辑结构——“集合”
      • 回顾:森林
      • 回忆:树的存储——双亲表示法
      • “并查集”的存储结构
      • “并查集”的基本操作
      • “并查集”的代码实现——初始化
      • “并查集”的代码实现——并、查
      • 时间复杂度分析
      • Union操作的优化
    • 5.5.2_2 并查集的进一步优化
      • 拓展:Find 操作的优化(压缩路径)
      • 并查集的优化
      • 快乐时刻
  • 知识回顾与重要考点
    • 5.5.1 哈夫曼树
    • 5.5.2_1 并查集
    • 5.5.2_2 并查集的进一步优化


第五章 树与二叉树

小题考频:30
大题考频:8


5.5 树与二叉树的应用

难度:☆☆☆☆

知识总览

5.5.1 哈夫曼树

在这里插入图片描述

5.5.2_1 并查集

在这里插入图片描述

5.5.2_2 并查集的进一步优化

——补充:并查集的终极优化


5.5.1 哈夫曼树

在这里插入图片描述

带权路径长度

在这里插入图片描述

带权路径长度:边数✖结点上的权值
Eg.在这里插入图片描述

树的带权路径长度:所有的叶子结点带权路径长度之和(WPL)

哈夫曼树的定义

在这里插入图片描述

只算叶子结点,带权路径长度之和
哈夫曼树WPL最小,也称最优二叉树
上图中中间两棵树的WPL=25为最小,那么这两棵树即哈夫曼树。

哈夫曼树的构造

在这里插入图片描述

  1. 选权值最小的两个结点让他们成为兄弟。
    Eg. 选a结点和c结点
  2. 把这两个结点的权值之和作为新树根结点的权值,然后继续选。
    Eg.新树为权值为3,选新树和e

重复上述操作。

哈夫曼树的一些性质:

  1. 每个初始结点最终都成为叶结点,且权值越小的结点到根结点的路径长度越大
  2. 两两结合需要进行n-1次,每结合一次会增加一个分支结点,哈夫曼树的结点总数为2n-1
  3. 哈夫曼树中不存在度为1的结点。
  4. 哈夫曼树并不唯一,但是WPL相同且最优。

Eg.2 另一种构造方法:
在这里插入图片描述
哈夫曼树的特性有什么用呢?


哈夫曼编码

发电报——点、划两个信号(二进制0/1)
在这里插入图片描述

如果采用ASCII编码,两人想传递100个答案,就需要操作8×100=800次,显然不高效。
字符集中只有四个字符,用两个二进制位就可以区分出四种状态:在这里插入图片描述
也属于固定长度编码,每个字符的二进制位长度相同。

80个C、10个A、8个B、2个D,可以映射成树,向左走是0,向右走是1:
在这里插入图片描述
那么所有答案的二进制长度就是最终的WPL=200,即操作200次就可以把答案传出去。

有没有更好的方案?
也就是说,让他们之间传递的二进制比特信息尽可能的少。
即构造的编码树的带权路径长度尽可能的小。

即构造哈夫曼树:

权值最小的是D和B,让其合并,接下来是A,最后是C

在这里插入图片描述

也就是说只要操作130次,就可以把答案传递出去了。

此处各字符对应的二进制长度不相同,这种编码方式就叫可变长度编码。

Q:此处不就是想用四个二进制串,来区分四个字符吗?字符A出现的频率也高,为什么非要用两个二进制位来表示A,而不用1来表示呢?这样也可以保证四个字符的二进制编码不一样。

在这里插入图片描述
A:用1来表示A,在树的形式中,A就变成了一个非叶子结点:

在这里插入图片描述

此时想要传递 CAAABD答案,就变成了0 111 111 110,接受这一段二进制数之后,要把信息翻译成A、B、C、D,就会变成C(0)、B(111)、B(111)、D(110),那么就出现了歧义:
在这里插入图片描述
如果用左边的编码方案,可以得到正确结果:加粗样式

左边这种编码方式可以称为:前缀编码

任何一个编码都不是另一个编码的前缀——无歧义

在这里插入图片描述
有哈夫曼树得到哈夫曼编码——字符集中的每个字符作为一个叶子结点,各个字符出现的频度作为结点的权值,根据之前介绍的方法构造哈夫曼树

因为哈夫曼树并不唯一,所以哈夫曼编码也不唯一


应用:英文字母频次

在这里插入图片描述

注:不可以传答案!在这里插入图片描述


5.5.2_1 并查集

在这里插入图片描述

漏网之鱼:逻辑结构——“集合”

在这里插入图片描述

补一下没学过的集合,在数学里很常用

在这里插入图片描述
可以将所有元素划分为几个子集:
在这里插入图片描述
那么,在集合的关系之下,任意挑选出两个元素,两个元素间有什么关系呢?

A和H不属于同一个集合
A和E属于同一个集合

回顾:森林

也可以用树、森林这种表示方式来表达出各个元素之间的
在这里插入图片描述

把属于同一个集合的元素组织成一棵树,不同集合的元素放到不同的树里。

用互不相交的树,表示多个“集合”:
在这里插入图片描述

”:指定一个元素,判断到底属于哪一个集合
——从指定元素出发,一路向北,找到根结点,通过根结点判断属于哪个集合
如何判断两个元素是否属于同一个集合?
——分别查到两个元素的根,判断根结点是否相同即可,根结点不一样就是从属于不同的两个集合

在这里插入图片描述

”:把两个合集合并为一个合集
——让一棵树成为另一棵树的子树即可

并查集,本质上是表示一种集合的逻辑关系,对这个集合需要实现的基本操作就是并和查

用双亲表示法。


回忆:树的存储——双亲表示法

在这里插入图片描述

根结点A没有父结点,对应的数组元素是-1;
G这个结点在数组里的位置是6,其父结点是C,C的位置在数组里是2,那么G对应的数据元素就是2指向C的下标。
用一个静态数组描述出各个结点之间的父子关系,方法就是让孩子结点的元素指针指向其父结点所对应的数组下标。
这些指针都是往上指的,给定一个结点要找到结点的父结点,或者一路往上找到其根结点就会很容易。并且想让两棵树并为同一棵树,只需要让一棵树的根结点的parent指向另一棵树的根结点的编号。

使用双亲表示法并和查这两个操作实现起来都会非常方便。

查:找根结点;并:找一棵树的根结点指向另一棵树的根结点


“并查集”的存储结构

在这里插入图片描述
将刚才提到例子中的ABCD……M,分别给他们对应上一个静态的数组元素。

L结点数组下标为11,父结点是E结点数组下标为4,所以和L对应的数组元素S[ ]就是4:在这里插入图片描述
E的父结点是B,B的下标是1,那么E对应值为1:在这里插入图片描述
B的父结点是A,A的下标是0,那么B对应值为0:在这里插入图片描述
A是根,对应数组元素的值是-1

对于其他两棵树也以此类推。

总结并查集:
Q:对于n个数据元素,如何表示这些数据元素之间的集合关系,属于同一集合还是不同集合?
A:声明一个长度为n的int型数组S,用这个数组表示它们的集合关系,本质上就是树的双亲表示法。


“并查集”的基本操作

在这里插入图片描述

查:确定指定元素所属集合
——利用数组一路往上找到根结点
并:合并两个不相交的集合
——让一棵树的根结点所对应的数组的值指向另一棵树的下标

并查集(Disjoint Set)是逻辑结构——集合的一种具体实现,只进行“”和“”两种基本操作


“并查集”的代码实现——初始化

在这里插入图片描述
用一个int型的数组来表示刚开始的这些元素,此时并不知道这些元素到底是否属于同一个集合,可以初始化为各自独立的n个子集,所以初始化并查集时,将所有数组的元素数组的值全部赋值为-1。

表示每个元素之间是各成一派的,每个元素就是独立的一个子集。

初始化之后,就可以根据实际的业务需求来对各个元素,各个集合进行合并,如果两个元素应该划分到同一个子集,那么就把它们并到一起。


“并查集”的代码实现——并、查

在这里插入图片描述

Find操作:找L结点所属集合,用while循环,L是11号,指向4号E结点,指向1号B结点,指向0号A结点,A指向-1,为根结点,那么L就属于A统治的子集。

Union操作:要把绿色和紫色两个集合合并为一个,两个子集的根结点分别为A、C,即传入A和C的数组下标0和2,先判断当前要合并的两个集合是两个不同的集合(相同直接return),然后将一个根结点的数组指针指向另一个根结点,S[2] = 0,这个操作就让C连到A结点下。

Eg. 合并E和G结点:先对它们进行find,找到它们的根结点分别是哪个,然后对根结点进行Union操作合并。


时间复杂度分析

在这里插入图片描述
并:把两个根结点合并,时间复杂度: O ( 1 ) O(1) O(1)

查:查J。左边情况下,查1次(较好的情况);右边情况下,查n次【最坏的情况和树的高度h相关】,时间复杂度 O ( n ) O(n) O(n)

想要优化并查集的效率,那么就要在构造树的时候,让树的高度h尽量低!


Union操作的优化

在这里插入图片描述
是否可以让较小的树合并到较大的树呢?

  1. 如果大树合并到小树:
    在这里插入图片描述

树的高度增加了

  1. 让小树合并到大树:
    在这里插入图片描述

树的高度没有变化

思路:每一次Union都让小树合并到大树上,用根节点的绝对值表示树的结点总数:
在这里插入图片描述

A的值是-6,绝对值为6,代表树有6个结点;
C的值是-2,绝对值为2,代表树有2个结点;
D的值是-5,绝对值为5,代表树有5个结点;
结点总数少的树为小树,让小树的根结点的值指向大树的根结点,并更新大树的结点树,如C合并到A,A的值更新为-8

步骤:
首先判断这两棵树,哪棵更小(由于是负值,负值越大,绝对值越小,结点越少,是小树),C结点更小,要将C结点合并到A结点;
累加结点总数,把-2和-6进行相加;
把更小的树的根结点C指向更大的树的根结点,将S[2] = 0

在这里插入图片描述
再合并另外两棵树:
在这里插入图片描述
可以发现,通过小树合并到大树,树的高度并没有变化。

在这里插入图片描述
对Union进行优化后,树的高度不会超过 [ l o g 2 n ] + 1 [log_2n]+1 [log2n]+1
Find操作的最坏时间复杂度为: O ( l o g 2 n ) O(log_2n) O(log2n)


5.5.2_2 并查集的进一步优化

——补充:并查集的终极优化

拓展:Find 操作的优化(压缩路径)

在这里插入图片描述

要找结点L所属集合,从L出发到E到B到A,这条路径称为查找路径。

压缩路径——Find操作,先找到根节点,再将查找路径上所有结点都挂到根结点下:
在这里插入图片描述
在这里插入图片描述

A为根结点,从L出发可以一次查找这条查找路径上的各个结点,此时需要把查找路径上的结点全都挂到根结点A下面。

在这里插入图片描述
在这里插入图片描述

把L挂到A下

在这里插入图片描述
在这里插入图片描述

把E挂到A下

在这里插入图片描述

此时查找L只需要一次操作,也就是说查找L的路径长度就被压缩了。

给出指定x,找到x所属的根;
向上找到查找路径上的结点,挂到根结点下;

每次Find操作,先找根,再“压缩路径”,可使树的高度不超过𝑂(α(𝑛))。α(𝑛)是一个增长很缓慢的函数,对于常见的n值,通常α(𝑛)≤4,因此优化后并查集的Find、Union操作时间开销都很低

时间复杂度甚至可以 ≤ O ( 4 ) ≤O(4) O(4)

并查集的优化

在这里插入图片描述

Union优化思路:小树合并到大树,时间复杂度不超过 O ( l o g 2 n ) O(log_2n) O(log2n)
Find优化:先找到根节点,再进行“压缩路径”
核心思想:尽可能让树变矮

在这里插入图片描述

合并n个独立元素,需要进行n-1次的Union,每次都需要进行Find操作,所以取决于Find操作的时间复杂度(树高h)。

快乐时刻

请添加图片描述

可以体验模拟并查集算法
https://www.cs.usfca.edu/~galles/visualization/DisjointSets.html

请添加图片描述

以及各种算法
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html


知识回顾与重要考点

5.5.1 哈夫曼树

在这里插入图片描述

  • 树的带权路径长度(WPL)
  • 哈夫曼树
  • 构造哈夫曼树
  • 哈夫曼编发:可用于数据压缩

5.5.2_1 并查集

在这里插入图片描述

  • Union操作时,让小树并入大树
  • 优化后,树高≤ [ l o g 2 n ] + 1 [log_2n]+1 [log2n]+1
    Find -> O ( l o g 2 n ) O(log_2n) O(log2n)

5.5.2_2 并查集的进一步优化

在这里插入图片描述

合并n个独立元素,需要进行n-1次的Union,每次都需要进行Find操作,所以取决于Find操作的时间复杂度(树高h)。

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

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

相关文章

MybatisPlus详解

文章目录 1.MyBatisPlus的介绍1.1 MybatisPlus的特性讲解1.2 支持的数据库1.3 MybatisPlus的日志 2.映射2.1 自动映射规则2.2 表映射2.3 字段映射2.4 字段失效2.5 视图属性 3. 条件构造器3.1 等值查询3.1.1 eq3.1.2 allEq3.1.3 ne 不等于 3.2 范围查询3.2.1 gt 大于3.2.2 ge 大…

[Nacos] Nacos Client重要Api (一)

Instance:实例,代表一个Nacos Client主机实例。ServiceInfo:微服务信息实例。其包含着一个Instance列表。NamingService: 该接口只有一个实现类,NacosNamingService。通过这个类的实例,可以完成Client与Ser…

数据结构篇六:二叉树

文章目录 前言1. 树的概念及结构1.1 树的概念1.2 树的相关概念1.3 树的结构 2. 二叉树的概念及结构2.1 二叉树的概念2.2 特殊的二叉树2.3 二叉树的性质2.4 二叉树的存储结构 3. 二叉树的顺序结构及实现3.1 二叉树的顺序结构3.2 堆的概念及结构3.3 堆的实现3.3.1 堆的创建3.3.2 …

如何在命令提示符中备份Windows设备驱动程序

如果清理安装Windows,则需要为系统中的每个设备安装驱动程序。制造商可能不再提供其中一些设备驱动程序,或者你放错了制造商的驱动程序安装文件备份。 在进行干净安装之前备份设备驱动程序是个好主意,这样之后就可以根据需要轻松恢复这些驱动程序,我们可以按以下方法来备份…

跟着chatGPT学习:kubernetes中的Reflector、list-watcher、informer等概念

以下是我跟chatGPT学习kubernetes中Reflector、list-watcher、informer等的概念的过程 不敢保证chatGPT回答的百分之百准确。但是,确实帮助我了我理解! 最终学习的是下面的图, 1、在kubernetes中Reflector原理? 在Kubernetes…

PDF工具Adobe Arcrobat Pro DC下载安装教程

wx供重浩:创享日记 对话框发送:adobe 免费获取Adobe Arcrobat Pro DC安装包 Acrobat是一款PDF(Portable Document Format,便携式文档格式)编辑软件。借助它,您可以以PDF格式制作和保存你的文档 &#xff0c…

Oracle数据库服务器中了locked1勒索病毒的方式与破坏用友nchome配置文件方式

随着计算机技术的不断发展,网络安全问题也变得日益严峻。其中,勒索病毒就是一种非常危险的网络威胁。它可以通过加密受害者的文件或数据库,使其无法正常使用,然后向受害者勒索赎金以解密文件。而最近收到很多企业的求助&#xff0…

什么是语音识别的语音助手?

前言 语音助手已经成为现代生活中不可或缺的一部分。人们可以通过语音助手进行各种操作,如查询天气、播放音乐、发送短信等。语音助手的核心技术是语音识别。本文将详细介绍语音识别的语音助手。 语音识别的基本原理 语音识别是将语音信号转换为文本的技术。语音识…

Centos7升级gcc、g++版本

Centos7默认的 gcc版本是 4.8.5 默认使用yum install gcc安装出来的gcc版本也是是4.8.5。 1.首先查看自己的 gcc 版本 gcc -v g -v如果出现:bash: g: 未找到命令... 则安装g:遇到暂停时,输入y继续安装 yum install gcc-c然后输入&#xf…

38、Solr Integration(2)Install Solr

文章目录 38、Solr Integration(2)Install Solr下载启动创建Core填充数据搜索测试 38、Solr Integration(2)Install Solr 下载 进入Solr下载页面Solr Downloads - Apache Solr 下载需要的版本,这里下载最新版9.2.1&a…

为什么我们应该选择Renderbus瑞云渲染进行 EEVEE 渲染?

在某些情况下,用户需要高精度、快速的渲染,而 EEVEE的诞生就是为了满足这种需求。Eevee(Extra Easy Virtual Environment Engine)是 Blender 最新的内部渲染引擎,由用于 Epic Games 开发的虚幻引擎的相同代码提供支持…

内存基础知识

概述 内存可存放数据。程序执行前需要先将外存中的数据放到内存中才能被CPU处理,因为CPU处理速度过快,而从硬盘读取数据较慢,所以内存是为了缓和CPU和硬盘之间的读取速度矛盾 在多道程序环境下,系统中会有多个程序并发执行&…

Git——C站最详细的Git教程,一篇学会Git(window\linux通用)

Git——C站最详细的Git教程,一篇学会Git(window\linux通用) 文章目录 Git——C站最详细的Git教程,一篇学会Git(window\linux通用)Git简介Git作用为什么要进行源代码管理?Git的诞生Git管理源代码特点Git操作流程图解 工作区暂存区和仓库区工作区暂存区仓…

Qt中QSplitter使QWidget改变屏占比

Qt系列文章目录 文章目录 Qt系列文章目录前言一、QSplitter是什么?二、具体代码1.头文件2.实现文件 总结 前言 在Qt中把QWidget窗体三等分,我想实现QWidget中的三等分窗口能够像QDockWidget类一样用鼠标拖动这三等分窗体边缘使屏占比改变。一般我们会直…

微服务保护之初识Sentinel、流量控制、隔离和降级、授权规则、规则持久化

微服务保护 1.初识Sentinel 1.1.雪崩问题及解决方案 1.1.1.雪崩问题 微服务中,服务间调用关系错综复杂,一个微服务往往依赖于多个其它微服务。 如图,如果服务提供者I发生了故障,当前的应用的部分业务因为依赖于服务I&#xff…

redis高级篇(1)----redis的持久化

分布式缓存 单节点redis的问题: 1)数据丢失的问题,redis是基于内存来进行存储的,当服务器重启的时候可能会丢失数据 2)无法满足高并发场景 3)如果redis宕机,那么这个服务不可用,所以就需要有一种自动的故障恢复手段,必…

Python模糊控制

Python模糊控制 概念和术语 模糊逻辑(Fuzzy Logic)是一种方法论,其基础是可以在连续统一体上表达某物的“真实性”。这就是说某事不是真或假,而是部分正确或部分错误。 模糊变量(fuzzy variable)具有明确…

联想笔记本电脑可以开机但是无法进入到桌面怎么办?

联想笔记本电脑可以开机但是无法进入到桌面怎么办?有用户使用的联想笔记本电脑出现了一些问题,电脑启动的时候屏幕是可以亮的,但是却出现错误代码,无法进入到系统操作界面中。那么这个情况是怎么回事呢?来看看以下的解…

AI根据图片自动建模

暂时放弃了,没显卡,直接装不了 用的是一个git上的老项目3年前的,最近更新6个月,由facebook开发 GitHub - facebookresearch/pifuhd: High-Resolution 3D Human Digitization from A Single Image. 他需要的环境有 Python 3PyTo…

微信xr-frame官方案例基础能力之渲染目标

前言:什么是渲染目标?(详见:RenderTarget-渲染目标) 在3D计算机图形领域,渲染目标是现代图形处理单元(GPU)的一个特征,它允许将3D场景渲染到中间存储缓冲区或渲染目标纹理…