初知C++:AVL树

news2024/10/12 19:30:46

文章目录

  • 初知C++:AVL树
  • 1.AVL树的概念
  • 2.AVL树的是实现
    • 2.1.AVL树的结构
    • 2.2.AVL树的插入
    • 2.3.旋转
    • 2.4.AVL树的查找
    • 2.5.AVL树平衡检测

在这里插入图片描述

初知C++:AVL树

1.AVL树的概念

AVL树是最先发明的自平衡⼆叉查找树,AVL是⼀颗空树,或者具备下列性质的⼆叉搜索树:它的左右子树都是AV树,且左右子树的高度差的绝对值不超过1。AVL树是⼀颗高度平衡搜索⼆叉树,通过控制⾼度差去控制平衡。

• AVL树得名于它的发明者G.M.Adelson-Velsky和E.M.Landis是两个前苏联的科学家,他们在1962年的论⽂《Analgorithmfortheorganizationofinformation》中发表了它。

• AVL树实现这⾥我们引⼊⼀个平衡因⼦(balancefactor)的概念,每个结点都有⼀个平衡因⼦,任何结点的平衡因⼦等于右⼦树的⾼度减去左⼦树的⾼度,也就是说任何结点的平衡因⼦等于0/1/-1,AVL树并不是必须要平衡因⼦,但是有了平衡因⼦可以更⽅便我们去进⾏观察和控制树是否平衡,就像⼀个⻛向标⼀样。

• 思考⼀下为什么AVL树是⾼度平衡搜索⼆叉树,要求⾼度差不超过1,⽽不是⾼度差是0呢?0不是更好的平衡吗?画画图分析我们发现,不是不想这样设计,⽽是有些情况是做不到⾼度差是0的。⽐如⼀棵树是2个结点,4个结点等情况下,⾼度差最好就是1,⽆法作为⾼度差是0 。

AVL树整体结点数量和分布和完全⼆叉树类似,⾼度可以控制在 logN,那么增删查改的效率也可以控制在O(logN),相⽐⼆叉搜索树有了本质的提升。在这里插入图片描述

2.AVL树的是实现

2.1.AVL树的结构

在下图我们可以看到_parent指针,后续更新平衡因子,有很大的作用。
在这里插入图片描述

2.2.AVL树的插入

2.2.1 AVL树插⼊⼀个值的⼤概过程

  1. 插⼊⼀个值按⼆叉搜索树规则进⾏插⼊。

  2. 新增结点以后,只会影响祖先结点的⾼度,也就是可能会影响部分祖先结点的平衡因⼦,所以更新
    从新增结点->根结点路径上的平衡因⼦
    ,实际中最坏情况下要更新到根,有些情况更新到中间就可
    以停⽌了,具体情况我们下⾯再详细分析。

  3. 更新平衡因⼦过程中没有出现问题,则插⼊结束

  4. 更新平衡因⼦过程中出现不平衡,对不平衡⼦树旋转,旋转后本质调平衡的同时,本质降低了⼦树
    的⾼度,不会再影响上⼀层,所以插⼊结束。

2.2.2 平衡因⼦更新
更新原则:

平衡因⼦=右⼦树⾼度-左⼦树⾼度(也可以变为左子树的高度-右子树的高度)

只有⼦树⾼度变化才会影响当前结点平衡因⼦。

插⼊结点,会增加⾼度,所以新增结点在parent的右⼦树,parent的平衡因⼦++,新增结点在
parent的左⼦树,parent平衡因⼦–

parent所在⼦树的⾼度是否变化决定了是否会继续往上更新
更新停⽌条件:

更新后parent的平衡因⼦等于0,更新中parent的平衡因⼦变化为-1->0或者1->0,说明更新前
parent⼦树⼀边⾼⼀边低,新增的结点插⼊在低的那边,插⼊后parent所在的⼦树⾼度不变,不会
影响parent的⽗亲结点的平衡因⼦,更新结束。

更新后parent的平衡因⼦等于1或-1,更新前更新中parent的平衡因⼦变化为0->1或者0->-1,说
明更新前parent⼦树两边⼀样⾼,新增的插⼊结点后,parent所在的⼦树⼀边⾼⼀边低,parent所
在的⼦树符合平衡要求,但是⾼度增加了1,会影响arent的⽗亲结点的平衡因⼦,所以要继续向上
更新。

更新后parent的平衡因⼦等于2或-2,更新前更新中parent的平衡因⼦变化为1->2或者-1->-2,说
明更新前parent⼦树⼀边⾼⼀边低,新增的插⼊结点在⾼的那边,parent所在的⼦树⾼的那边更⾼
了,破坏了平衡,parent所在的⼦树不符合平衡要求,需要旋转处理,旋转的⽬标有两个:1、把
parent⼦树旋转平衡。2、降低parent⼦树的⾼度,恢复到插⼊结点以前的⾼度。所以旋转后也不
需要继续往上更新,插⼊结束。

更新到10结点,平衡因⼦为2,10所在的⼦树已经不平衡,需要旋转处理
在这里插入图片描述
更新到中间结点,3为根的⼦树⾼度不变,不会影响上⼀层,更新结束
在这里插入图片描述
最坏更新到根停⽌
在这里插入图片描述
2.2.3插⼊结点及更新平衡因⼦的代码实现
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3.旋转

2.3.1 旋转的原则

  1. 保持搜索树的规则
  2. 让旋转的树从不满⾜变平衡,其次降低旋转树的⾼度
    旋转总共分为四种,左单旋/右单旋/左右双旋/右左双旋。
    说明:下⾯的图中,有些结点我们给的是具体值,如10和5等结点,这⾥是为了⽅便讲解,实际中是什
    么值都可以,只要⼤⼩关系符合搜索树的规则即可。

2.3.2 右单旋

本图1展⽰的是10为根的树,有a/b/c抽象为三棵⾼度为h的⼦树(h>=0),a/b/c均符合AVL树的要
求。10可能是整棵树的根,也可能是⼀个整棵树中局部的⼦树的根。这⾥a/b/c是⾼度为h的⼦树,
是⼀种概括抽象表⽰,他代表了所有右单旋的场景,实际右单旋形态有很多种,具体图2/图3/图4/
图5进⾏了详细描述。

在a⼦树中插⼊⼀个新结点,导致a⼦树的⾼度从h变成h+1,不断向上更新平衡因⼦,导致10的平
衡因⼦从-1变成-2,10为根的树左右⾼度差超过1,违反平衡规则。10为根的树左边太⾼了,需要
往右边旋转,控制两棵树的平衡。

旋转核⼼步骤,因为5<b⼦树的值<10,将b变成10的左⼦树,10变成5的右⼦树,5变成这棵树新
的根,符合搜索树的规则,控制了平衡,同时这棵的⾼度恢复到了插⼊之前的h+2,符合旋转原
则。如果插⼊之前10整棵树的⼀个局部⼦树,旋转后不会再影响上⼀层,插⼊结束了。

下面五张图分别为右旋的各种情况!!!!!(请仔细观看有利于理解哦)
图1:
在这里插入图片描述
图2:
在这里插入图片描述
图3:
在这里插入图片描述
图4:
在这里插入图片描述
图5:
在这里插入图片描述

2.3.3 右单旋代码实现
这里传过去的parent是平衡因子为2或者-2的节点!在这里插入图片描述
2.3.4左单旋
•本图6展⽰的是10为根的树,有a/b/c抽象为三棵⾼度为h的⼦树(h>=0),a/b/c均符合AVL树的要求。10可能是整棵树的根,也可能是⼀个整棵树中局部的⼦树的根。这⾥a/b/c是⾼度为h的⼦树,是⼀种概括抽象表⽰,他代表了所有右单旋的场景,实际右单旋形态有很多种,具体跟上⾯左旋类似。

•在a⼦树中插⼊⼀个新结点,导致a⼦树的⾼度从h变成h+1,不断向上更新平衡因⼦,导致10的平衡因⼦从1变成2,10为根的树左右⾼度差超过1,违反平衡规则。10为根的树右边太⾼了,需要往左边旋转,控制两棵树的平衡。

•旋转核⼼步骤,因为10<b⼦树的值<15,将b变成10的右⼦树,10变成15的左⼦树,15变成这棵树新的根,符合搜索树的规则,控制了平衡,同时这棵的⾼度恢复到了插⼊之前的h+2,符合旋转原则。如果插⼊之前10整棵树的⼀个局部⼦树,旋转后不会再影响上⼀层,插⼊结束了。
在这里插入图片描述
2.3.5左单旋代码实现
在这里插入图片描述

2.3.6左右双旋
通过图7和图8可以看到,左边⾼时,如果插⼊位置不是在a⼦树,⽽是插⼊在b⼦树,b⼦树⾼度从h变成h+1,引发旋转,右单旋⽆法解决问题,右单旋后,我们的树依旧不平衡。右单旋解决的纯粹的左边⾼,但是插⼊在b⼦树中,10为跟的⼦树不再是单纯的左边⾼,对于10是左边⾼,但是对于5是右边⾼,需要⽤两次旋转才能解决,以5为旋转点进⾏⼀个左单旋,以10为旋转点进⾏⼀个右单旋,这棵树这棵树就平衡了。
图7:
在这里插入图片描述
图8:
在这里插入图片描述
• 图7和图8分别为左右双旋中h0和h1具体场景分析,下⾯我们将a/b/c⼦树抽象为⾼度h的AVL⼦树进⾏分析,另外我们需要把b⼦树的细节进⼀步展开为8和左⼦树⾼度为h-1的e和f⼦树,因为我们要对b的⽗亲5为旋转点进⾏左单旋,左单旋需要动b树中的左⼦树。b⼦树中新增结点的位置不同,平衡因⼦更新的细节也不同,通过观察8的平衡因⼦不同,这⾥我们要分三个场景讨论。

• 场景1:h>=1时,新增结点插⼊在e⼦树,e⼦树⾼度从h-1并为h并不断更新8->5->10平衡因⼦,引发旋转,其中8的平衡因⼦为-1,旋转后8和5平衡因⼦为0,10平衡因⼦为1。

• 场景2:h>=1时,新增结点插⼊在f⼦树,f⼦树⾼度从h-1变为h并不断更新8->5->10平衡因⼦,引发旋转,其中8的平衡因⼦为1,旋转后8和10平衡因⼦为0,5平衡因⼦为-1。

• 场景3:h==0时,a/b/c都是空树,b⾃⼰就是⼀个新增结点,不断更新5->10平衡因⼦,引发旋转,其中8的平衡因⼦为0,旋转后8和10和5平衡因⼦均为0。
在这里插入图片描述

2.3.7 左右双旋代码实现
在这里插入图片描述
2.3.8右左双旋
•跟左右双旋类似,下⾯我们将a/b/c⼦树抽象为⾼度h的AVL⼦树进⾏分析,另外我们需要把b⼦树的细节进⼀步展开为12和左⼦树⾼度为h-1的e和f⼦树,因为我们要对b的⽗亲15为旋转点进⾏右单旋,右单旋需要动b树中的右⼦树。b⼦树中新增结点的位置不同,平衡因⼦更新的细节也不同,通过观察12的平衡因⼦不同,这⾥我们要分三个场景讨论。

•场景1:h>=1时,新增结点插⼊在e⼦树,e⼦树⾼度从h-1变为h并不断更新12->15->10平衡因⼦,引发旋转,其中12的平衡因⼦为-1,旋转后10和12平衡因⼦为0,15平衡因⼦为1。

•场景2:h>=1时,新增结点插⼊在f⼦树,f⼦树⾼度从h-1变为h并不断更新12->15->10平衡因⼦,引发旋转,其中12的平衡因⼦为1,旋转后15和12平衡因⼦为0,10平衡因⼦为-1。

• 场景3:h==0时,a/b/c都是空树,b⾃⼰就是⼀个新增结点,不断更新15->10平衡因⼦,引发旋转,其中12的平衡因⼦为0,旋转后10和12和15平衡因⼦均为0。
在这里插入图片描述
2.3.9右左双旋代码实现
在这里插入图片描述

2.4.AVL树的查找

在这里插入图片描述

2.5.AVL树平衡检测

我们实现的AVL树是否合格,我们通过检查左右⼦树⾼度差的的程序进⾏反向验证,同时检查⼀下结点的平衡因⼦更新是否出现了问题。(空树也是AVL树哦!!!!)

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

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

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

相关文章

中国剩余定理 C++

题目 解题思路 原链接&#xff1a;https://www.acwing.com/solution/content/3539/ 大致步骤&#xff1a; 将第2,3,4…n个方程不断与第一个方程合并&#xff0c;得到方程a1k1a2k2m2-m1;用扩展欧几里得算法解出a1k1a2k2gcd(a1, a2)的结果&#xff0c;再将结果扩大(m2-m1)/d倍即…

2-laravel-路由配置

文章目录 定义控制器设计控制器设置路由启动服务 基本路由视图路由建立视图路由建立视图文件 控制器视图路由创建视图二级目录控制器 定义控制器 打开laravel 工程 建立一个 Demo 名字的控制器去集成 模板控制器 安装两个插件 设计控制器 <?phpnamespace App\Http\…

关于电动自行车新增的通信功能要求如下

1、 电动自行车应具有采用TLS加密的4G或5G公网通信模块&#xff0c;或类似功能的地面通信模块。 注:根据我国无线电管理有关规定&#xff0c;可能需要对无线电发射模块或整车进行无线电发射设备型号核准。 2、通信模块具备向电动自行车管理平台发送以下动态安全监测信息的功能&…

SpringBoot项目升级JDK版本(1.8 => 17)

项目&#xff1a;这里使用gitee上一个开源项目做测试《SpringBoot 流媒体项目》 工具&#xff1a;Intellij IDEA 一、下载项目&#xff08;git clone …&#xff09; 1、打开 pom.xml 看一下 2、启动项目&#xff0c;记住它最原本的样子先。成功启动后控制台后面是会输出地址…

怎么进行智能配音?一文告诉你

如何给文字智能配音呢&#xff1f;将文字转化为生动的语音&#xff0c;是提升内容吸引力的有效方式。 无论是制作视频、音频课程还是电子读物&#xff0c;合适的配音都能让信息传递更加高效。 如果你正寻找简单易用的方法来给文字添加配音&#xff0c;这里有几款智能配音软件…

0基础能不能转行做网络安全?

0基础能不能转行做网络安全&#xff1f;网络安全人才发展路线 最近有同学在后台留言&#xff0c;0基础怎么学网络安全&#xff1f;0基础可以转行做网络安全吗&#xff1f;以前也碰到过类似的问题&#xff0c;想了想&#xff0c;今天简单写一下。 我的回答是先了解&#xff0c…

Java对接ModbusRTU协议案例测试(相关代码及调试工具使用)

目的 在无设备的情况下&#xff0c;电脑搭建虚拟环境&#xff0c;进行代码编写以及测试 准备工作 一.测试工具 1.模拟虚拟串口工具&#xff0c;modbus RTU使用一问一答模式进行数据交互。 本文内容&#xff1a;模拟主站从站发送读取数据 2.个人设置&#xff1a;COM10为主站&am…

simulink分段函数

两段函数 20<v<60为真时&#xff0c;输出0.8 20<v<60为假时&#xff0c;即v<20或v>60时&#xff0c;输出0v>20时&#xff0c;输出0.8 v<20时&#xff0c;输出0 n段函数 n-1个switch模块

d3dcompiler_43.dll 文件的缺失常见方法分析,一键修复d3dcompiler_43.dll

在使用电脑的过程中&#xff0c;d3dcompiler_43.dll 文件的缺失是一个常见的技术挑战&#xff0c;这一问题通常会影响到基于Direct3D技术的应用程序的正常运行&#xff0c;可能导致程序启动失败或运行错误。d3dcompiler_43.dll 是DirectX组件的一部分&#xff0c;专责于编译用于…

CLIP图文多模态模型onnxruntime和tensorrt推理

首先下载github项目&#xff1a;https://github.com/Lednik7/CLIP-ONNX 修改clip_onnx/utils.py第61行opset_version12为opset_version15 , 运行测试脚本&#xff1a; import clip from PIL import Image import numpy as np# ONNX不支持CUDA model, preprocess clip.load(&q…

FFmpeg的简单使用【Windows】--- 视频倒叙播放

实现功能 点击【选择文件】按钮可以选择视频&#xff0c;当点击【开始处理】按钮之后&#xff0c;会先将视频上传到服务器&#xff0c;然后开始进行视频倒叙播放的处理&#xff0c;当视频处理完毕之后会将输出的文件路径返回&#xff0c;同时在页面中将处理好的视频展示出来。…

SpringBoot Data JPA基本使用

一、项目起步 1.1 pom配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><dependency><groupId>org.springframework.boot</groupId><…

基于ssm的美妆分享网站的设计与实现

文未可获取一份本项目的java源码和数据库参考。 经济的快速发展&#xff0c;人均可支配收入提高&#xff0c;多数年轻人化妆理念都已经改变。在化妆品消费渗透率不断提升、核心化妆人口持续扩散因素的多重影响下&#xff0c;化妆品行业持续高速增长&#xff0c;但是我们对美妆的…

C++题 十进制转二进制

文章目录 1. 使用C20 std::format2. 使用 std::bitset 类3. 手动实现十进制到二进制的转换反过来&#xff0c;手动二进制到十进制 VisualStudio2022使用C&#xff0c;进行十进制到二进制的转换&#xff0c;常见的实现方式 1. 使用C20 std::format 需要将VisualStudio默认的标准…

信息学奥赛复赛复习16-CSP-J2022-01乘方-循环特判、pow函数、快速幂

PDF文档回复:20241012 此前解析题&#xff0c;P8813 [CSP-J 2022] 乘方&#xff0c;给出了循环的解题思路&#xff0c;当时在洛谷提交是通过的&#xff0c;后台收到留言&#xff0c;a1,b1e9会炸吧&#xff1f;&#xff0c;确实啊整除要求1s内循环次数最大可以到10^7,现在测试数…

微信自动化工具,让多微管理更轻松更高效!

对于多个微信账号的管理&#xff0c;往往会让人感到繁琐和耗时。 这时&#xff0c;通过个微管理系统实现微信自动化设置&#xff0c;将大大提升我们的管理效率。 1、批量自动加好友 只需将客户号码一次性导入系统&#xff0c;设置好加好友规则&#xff0c;系统便会自动发送加…

PS文件保存后突然消失?别急,这里有7种解决方案!

咨询&#xff1a;“我刚做完的PS文件&#xff0c;保存得好好的&#xff0c;怎么就突然消失了呢&#xff1f;连回收站里都没有&#xff0c;这可怎么办才好。” 面对PS&#xff08;Photoshop&#xff09;文件在保存后突然消失的情况&#xff0c;许多设计师和图像处理爱好者可能会…

List的实现类

1.ArrayList&#xff08;数组&#xff09; &#xff08;1&#xff09;代码 新建学生类&#xff1a; package com.collection;public class Student {private String name;private int age;//添加构造方法 都是使用altenter快捷键public Student() {this.name name;this.age…

OCR经典神经网络(二)文本检测算法DBNet算法原理及其在icdar15数据集上的应用

OCR经典神经网络(二)文本检测算法DBNet算法原理及其在icdar15数据集上的应用 场景文本检测任务&#xff0c;一直以来是OCR整个任务中最为重要的一环。虽然有一些相关工作是端对端的&#xff0c;但是从工业界来看&#xff0c;相关落地应用较为困难。因此&#xff0c;两阶段的OC…

RUM性能优化之图片加载

作者&#xff1a;三石 在现代Web开发中&#xff0c;图片作为内容表达的核心元素&#xff0c;其加载效率直接影响到页面的整体性能和用户体验。随着高清大图和动态图像的普及&#xff0c;优化图片加载变得尤为重要。RUM作为一种主动监测技术&#xff0c;能够帮助开发者从真实用户…