AVLTree深度剖析(单旋)

news2024/11/24 2:57:04

前言

二叉树搜索树是存在一定的缺陷问题的,当我们要插入的数据是有序,或者说接近于有序,,二叉搜索树及有可能退化为单支树,查找元素相当于在顺序表当中搜索元素,效率低下

---------------------------------------------------------------------------------------------------------------------------------

AVL树的概念

解决上述问题的方法是两位俄罗斯科学家发明的: 当向二叉搜索树当中插入新节点后,如果能保证每个节点的左右子树高度差的绝对值不超过1(超过对树当中的节点做调整),降低树的高度,从而减少平均搜索长度

一颗AVL树或者是空树,或者是具有以下性质的二叉搜索树:

1.它是左右子树都是AVL树

2.左右子树高度之差(简称平衡因子)的绝对值不超过(-1   /   0    /1)  平衡因子:右子树的高度-左子树的高度

 如果一颗二叉搜索树是高度平衡的,它就是AVL树,如果它有n个节点,其高度可保持在log_2(N),那么搜索的时间复杂度以2为底N的对数!!!

log以2为底n的对数是查找效率非常高的了,假设将我们全中国人口14亿人的数据保存在这样的一颗树当中,那么只需要查找31次,最多31次,高度次,是非常恐怖的!!!

-----------------------------------------------------------------------------------------------------------------------

实现AVL树

 为何我们在这里使用三叉链呢??

当我插入一个新节点之后,这棵树还是不是平衡树,我们就看高度差,不过呢平衡因子就是高度差的一个结果,在插入新节点之后我们得想办法更新平衡因子,更新的是祖先的平衡因子

 ----------------------------------------------------------------------------------------------------------------------

insert插入的实现

按照我们以前的搜索树的insert,到这一步也就结束了,但是我们这里插入之后,我们得控制平衡

有可能插入之后还是平衡的,也可能插入之后,不平衡了

我们在判断这颗树,或者子树是否平衡时,是通过平衡因子判断的,所以在判断是否平衡之前,得先更新平衡因子

更新平衡因子的规则:

1.新增在右,parent->_bf++    ,新增在左,parent->_bf--;

 2.更新后,parent->_bf  == 1或者-1  ,说明parent插入之前的平衡因子是0,说明左右子树高度相等,插入有一边高,parent的高度变了,继续往上更新

更新后,parent->_bf == 1   or  -1   ,  1代表右边高, -1代表左边高  ,这里要不要继续往上更新平衡因子的因素取决于,parent子树的高度是否变化,parent的平衡因子变为-1或者1,高度肯定的变了,为什么呢? 因为++  或者 -- 之后变为 -1 或者1  说明在不插入新节点之前是左右子树高度是一样的

我们在这里有没有可能parent的平衡因子是  2或者  -2   ,加加 减减之后变为 1或者-1 呢??肯定是不可能的,如果之前是2或者-2的画早就不平衡了,之前就应该做调整

3.更新后,parent->_bf ==0  ,说明parent插入之前的平衡因子  -1   或者  1  加加或者减减一下,说明左右子树一边高一边低,插入之后,两边一样高,说明插入填上了矮的那一边,parent所在的子树高度不变,不需要继续向上更新

 4.更新后,parent->_bf == 2或者-2  ,说明parent插入前的平衡因子是  1or  -1  ,说明在插入之前已经是平衡的临界值了,现在插入变成2或者-2  ,说明打破平衡,parent所在的子树,需要进行旋转处理

5.更新后,parent->_bf >2   or   parent->_bf < -2 ,不可能,如果存在则说明插入之前就不是AVL树,那需要去检查之前的操作问题

 此时这颗树,并没有发生旋转,但是快要发生旋转了,倾向于旋转了,好几个节点的平衡值都在临界值。

 -------------------------------------------------------------------------------------------------------------

我们现在写更新平衡因子的代码  -->   最坏的情况就是不断更新,更新到根节点,也可能中间就停止了

 接下来就是要处理我们的旋转问题了

在这里我们需要想办法去处理,无论是整颗树,还是子树

我们在这里处理的原则 :

1.旋转成平衡树

2.保持搜索树的规则

 对上面的情况网上有人做了归类

左单旋

 当h==2的时候,就已经有36种情况了

当h==3时,情况就更多了

如果我们要列举这里的情况,是无穷无尽的,但是对于上面情况当中的哪一种,我们的处理动作都是一样的

所以插入的时间复杂度是  高度次更新平衡因子+旋转的时间复杂度(O(1))

--------------------------------------------------------------------------------------------------------------------------

右单旋

a、b、c是h大于等于0的平衡树

 

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

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

相关文章

LeetCode1657. 确定两个字符串是否接近

确定两个字符串是否接近 提示 中等 55 相关企业 如果可以使用以下操作从一个字符串得到另一个字符串&#xff0c;则认为两个字符串 接近 &#xff1a; 操作 1&#xff1a;交换任意两个 现有 字符。 例如&#xff0c;abcde -> aecdb 操作 2&#xff1a;将一个 现有 字符的每…

仓库管理软件有哪些功能?2023仓库管理软件该如何选?

对于现代企业或批发零售商&#xff0c;高效的仓库管理是确保供应链运作顺畅、库存控制精准的关键要素。在数字化时代&#xff0c;越来越多的企业和商户意识到采用仓库管理软件的重要性。 无论您是中小型企业还是中小商户&#xff0c;仓库管理都是不可忽视的一环。 一、选择仓库…

微信小程序开发闭到眼睛创建分包和详细解释

一、普通分包创建 1.介绍 说明&#xff1a;微信小程序分包是指将小程序的代码和资源按照一定规则分成多个包&#xff0c;减少首次加载时间&#xff0c;提高用户体验。分包可以有效减少小程序包的总大小&#xff0c;提高启动速度&#xff0c;减少首次加载时间。分包可以根据业…

实现小程序商城首页【源码公开】

效果图 页面源码 <view class"index-container"><view class"header"><!--搜索框【仅样式&#xff0c;不做处理】 start--><van-search bindtap"clickSearch" disabled shape"round" background"#9c7bf0&q…

在idea中搭建微服务项目(22版),详细教程

1.创建新的项目 2.创建的项目类型为SpringBoot 选择创建后再选择新建项目 3. 将新建的项目中不需要的东西都给删了,只留下pom文件即可 修改pom文件的版本 <version>2.1.6.RELEASE</version> 导入所需要的jar包,将原来<dependencies>中的依赖覆盖掉 <!-- …

10 卷积网络 convolutional networks

卷积 如果将图片从 H ∗ W ∗ C H*W*C H∗W∗C 拉伸到 N ∗ 1 N*1 N∗1 的维度&#xff0c;而参数矩阵又是 N ∗ M N*M N∗M 的大小。N很大&#xff0c;M也很大。整个网络中的参数量会变得巨大。 卷积过程&#xff0c;使用一个filter 在整个图片上滑动。 当然输入的图象可…

普通人决策正确率如何提升

简洁回复&#xff1a;非常非常非常难&#xff0c;几乎不能。 举个简单例子&#xff1a; 高考报志愿&#xff0c;能走到高考这一步的并取得成绩的&#xff0c;从幼儿园到高中&#xff0c;3633&#xff0c;这个赛道奔跑了15年。 大部分人这里指的是考生自己&#xff0c;花费在填…

Unity LayerMask原理和判断包含关系

在本文之前&#xff0c;请先了解全部位操作的含义&#xff0c;否则继续下去会很困难。 本质&#xff1a;32位整数的每一位表示一个层 LayerMask本质上是一个32位的整数(Int32 ,int)&#xff0c;每个位代表一个图层&#xff0c;因此LayerMask最多可以表示32个图层&#xff08;0…

Vue3组件间的通信方式

目录 1.props父向子组件通信 2.自定义事件 子向父组件通信 3.全局事件总线 4.v-model组件通信&#xff08;父子组件数据同步&#xff09; 绑定单个数据同步 绑定多个数据同步 5.useAttrs组件通信 6.ref与$parent ref获取子组件实例对象 $parent获取父组件实例对象 7.p…

大采购,助力提升国有企业采购供应链管理水平

2023年7月11日-12日&#xff0c;由中国物流与采购联合会主办、北京筑龙承办的主题为“数智赋能创新发展”的“第四届国有企业数智化采购与智慧供应链论坛”在北京盛大举行。来自中央企业、地方国企采购与供应链部门相关负责人、业界专家、行业媒体代表等齐聚一堂、共襄盛会。北…

HCIP第十二天

题目 拓扑图 sw1、sw2、sw3分别创建VLAN、划分接口&#xff0c;配置干道 VLAN间路由 所有PC通过DHCP获取IP地址 PC1/3可以正常访问PC2/4/5/6

【学会动态规划】解码方法(4)

目录 动态规划怎么学&#xff1f; 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后&#xff1a; 动态规划怎么学&#xff1f; 学习一个算法没有捷径&#xff0c;更何况是学习动态规划&#xff0c; 跟我…

国内流行的数据可视化软件工具

在信息爆炸的时代&#xff0c;越来越多的数据堆积如山。但是&#xff0c;这些密集的数据没有重点且可读性较差。因此&#xff0c;我们需要数据可视化来帮助数据易于理解和接受。相比之下&#xff0c;可视化更直观、更有意义&#xff0c;使用适当的数据可视化工具来可视化数据非…

C++入门 - 1(几分钟让你快速入门C++)

c入门 1. C关键字(C98)2. 命名空间2.1 命名空间定义2.2 命名空间使用 3. C输入&输出4.缺省参数4.1 缺省参数概念4.2 缺省参数分类 5. 函数重载5.1 函数重载概念5.2 C支持函数重载的原理--名字修饰(name Mangling)提问&#xff1a;C语言中为什么没有函数重载呢&#xff1f; …

常见的网络拓扑结构,你都看懂吗

常见的网络拓扑结构有以下6种&#xff1a;1.总线型网络拓扑结构&#xff1b;2.星型网络拓扑结构&#xff1b;3.环形网络拓扑结构&#xff1b;4.树型网络拓扑结构&#xff1b;5.网状网络拓扑结构&#xff1b;6.混合网络型拓扑结构。其中&#xff0c;“总线型网络拓扑结构”是所有…

Redis学习(三)持久化机制、分布式缓存、多级缓存、Redis实战经验

文章目录 分布式缓存Redis持久化RDB持久化AOF持久化 Redis主从Redis数据同步原理全量同步增量同步 Redis哨兵哨兵的作用和原理sentinel&#xff08;哨兵&#xff09;的三个作用是什么&#xff1f;sentinel如何判断一个Redis实例是否健康&#xff1f;master出现故障后&#xff0…

QT中级(7)- 串口工具

QT中级&#xff08;7&#xff09;- 串口工具 1 串口通信的基础知识2 需要准备的工具3 Qt中的串口编程3.1 引入QSerialPort3.2 设置参数3.3 读取数据3.4 发送数据 4 源码 1 串口通信的基础知识 串行与并行&#xff1a;串口通信是一种串行通信方式。这意味着数据一位一位地通过通…

面试中关于自动化测试的认识

目录 一、什么是自动化测试&#xff0c;自动化测试的优势是什么&#xff1f; 二、什么样的项目比较适合做自动化测试&#xff0c;什么样的不适合做自动化测试&#xff1f; 三、在制定自动化测试计划的时候一般要考虑哪些点&#xff1f; 四、编写自动化脚本时的一些规范&…

02. 第一个Docker部署应用

目录 1、前言 2、Docker部署Nginx 3、修改镜像存储路径 3.1、默认存储路径 3.2、自定义存储路径 3.2.1、创建自定义的镜像存储路径 3.2.2、创建Docker守护进程的配置文件 3.2.3、重启docker服务 3.2.4、重新查看docker路径 4、配置镜像加速 4.1、配置阿里镜像加速器…

Unity 之 安卓平台上架隐私问题解决方案

Unity 之 助力游戏增长 -- 解决隐私问题 一&#xff0c;平台测试隐私问题二&#xff0c;解决方式一2.1 勾选自定义Mainifest2.2 修改自定义Mainifest2.3 隐私协议弹窗逻辑 三&#xff0c;解决方式二3.1 导出安卓工程3.2 创建上层Activity3.3 配置AndroidManifest 四&#xff0…