【C++】AVL树的了解和简单实现

news2024/11/14 4:36:39

目录

AVL树的概念 

AVL树介绍 

平衡因子 

 AVL树的插入 

平衡因子的更新 

【1】平衡因子为0

【2】平衡因子为1/-1

【3】平衡因子为2/-2

选择的处理

旋转的原则 

右单旋 

具体的三种情况: 

​编辑 所有情况的概念图:

对于父亲指针的处理 :

 左单旋

具体的三种情况: 

左右双旋 

具体情况例子: 

右左双旋 

代码示例: 


AVL树的概念 

  • AVL数是一棵具有二叉搜索树性质,并且左右子树的高度差不超过1的树
  • AVL树还可以是一棵空树 

AVL树的发明者:G.M.Adelson-Velsky和E.M.Landis是两个前苏联的科学家 

AVL树介绍 

  • AVL树遵循二叉搜索树的规则:左边小于根节点,右边大于根节点
  • 本次AVL树的实现借助平衡因子的概念 

平衡因子 

  • 每个节点都有一个平衡因子,该平衡因子等于右子树的高度减去左子树的高度
  • 可以说任何节点的平衡因子可能是0/1/-1
  • 平衡因子并不是AVL树的必须品,但它可以作为一个观察风向标,使我们更加方便观察和控制AVL树的平衡  

注意: 如果平衡因子大于等于2,说明该树已经不平衡不再是一棵AVL树,需要调节平衡!

AVL树是高度平衡的二叉搜索树这个高度为什么设置为1,而不是0呢,因为存在某些特殊情况,高度无法达到0 

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

 AVL树的插入 

  • 按照二叉搜索树的规则插入
  • 根据新增的节点更新平衡因子 

平衡因子的更新 

 更新规则

  • 平衡因⼦=右子树⾼度-左子树⾼度
  • 只有⼦树高度变化才会影响当前结点平衡因⼦
  • 插⼊结点,会增加⾼度,所以新增结点在parent的右⼦树,parent的平衡因⼦++,新增结点在 parent的左子树,parent平衡因⼦--
  • parent所在子树的⾼度是否变化决定了是否会继续往上更新

 更新停止条件

【1】平衡因子为0

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

【2】平衡因子为1/-1

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

  • 更新到中间结点,3为根的⼦树⾼度不变,不会影响上⼀层,更新结束
  • 最坏更新到根停⽌ 

【3】平衡因子为2/-2

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

 

选择的处理

旋转的原则 

  • 保持搜索树的规则
  • 让旋转的树从不平衡变平衡,其次降低旋转树的⾼度
  • 旋转总共分为四种,左单旋/右单旋/左右双旋/右左双旋 

右单旋 

具体的三种情况: 

 

 所有情况的概念图:

 触发右单旋的条件:parent->_bf == -2 && cur->_bf == -1

右单旋的具体操作:5<b子树的数据<10,进行旋转时,我们将b子树作为10的左子树,然后10作为5的右子树,同样我们也需要更改他们的_parent节点,最后5节点和10节点的平衡因子为0 

对于父亲指针的处理 :

 当我们完成上述的连接之后我们需要考虑subL的父亲节点是什么

  • 1. 原本的parent是_root,那么新的subL将成为_root节点,其_parent->nullptr
  • 2. 原本的parent是其他节点,那么subL的父亲节点需要判断原本的parent在他的_parent的左子树还是右子树,指向subL

 左单旋

具体的三种情况: 

 

其他情况处理与右单旋相似 

左右双旋 

具体情况例子: 

 

以上如果我们只通过一个单旋操作是无法实现条件平衡的 

 

  • 先对subL进行一个左单旋,再对parent进行一个右单旋 
  • 根据图像观察我们可以发现,最后的步骤可以简化为将subLR的左子树给subL的右,bf++;subLR的右子树给parent的左,bf--; 我们只需要记录subLR的bf即可,如果subLR的bf为0,那么所有参与节点的bf最后都为0;如果subLR的bf为1,那么subL->_bf=-1;如果subLR的bf为-1,那么parent->_bf=1; 

右左双旋 

 

  • 先对subR进行一个右单旋,再对parent进行一个左单旋 
  • 根据图像观察我们可以发现,最后的步骤可以简化为将subRL的右子树给subR的左,bf--;subRL的左子树给parent的右,bf++; 我们只需要记录subRL的bf即可,如果subRL的bf为0,那么所有参与节点的bf最后都为0;如果subRL的bf为1,那么parent->_bf=-1;如果subRL的bf为-1,那么subR->_bf=1; 

代码示例: 

C++_Test_AVLTree_2024_10_29 · 阳区欠/CPlusPlus学习仓库 - 码云 - 开源中国 

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

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

相关文章

使用 PageHelper 在 Spring Boot 项目中实现分页查询

目录 前言1. 项目环境配置1.1 添加 PageHelper 依赖1.2 数据库和 MyBatis 配置 2. 统一的分页响应类3. 使用 PageHelper 实现分页查询3.1 Service 层分页查询实现3.2 PageHelper 分页注意事项 4. 控制层调用示例5. 常见问题与解决方案5.1 java.util.ArrayList cannot be cast t…

丹摩征文活动 | 丹摩智算:大数据治理的智慧引擎与实践探索

丹摩DAMODEL&#xff5c;让AI开发更简单&#xff01;算力租赁上丹摩&#xff01; 目录 一、引言 二、大数据治理的挑战与重要性 &#xff08;一&#xff09;数据质量问题 &#xff08;二&#xff09;数据安全威胁 &#xff08;三&#xff09;数据管理复杂性 三、丹摩智算…

彻底理解ARXML中的PDU

文章目录 一、DBC报文信号的发送二、ARXML报文信号的发送2.1 什么是PDU2.2 PDU的类型2.3 Container-I-PDU的发送 三、小结 在CANFD支持可变速率和更大的数据长度&#xff08;64字节&#xff09;的情况下&#xff0c;可以使用DBC和ARXML两种数据库格式来进行报文通信&#xff0c…

探索MoviePy:Python视频编辑的瑞士军刀

文章目录 &#x1f3ac; 探索MoviePy&#xff1a;Python视频编辑的瑞士军刀第一部分&#xff1a;背景介绍第二部分&#xff1a;MoviePy是什么&#xff1f;第三部分&#xff1a;如何安装MoviePy&#xff1f;第四部分&#xff1a;MoviePy的基本函数使用方法1. 视频剪辑2. 视频拼接…

前端请求后端php接口跨域 cors问题

只需要后端在网站的入口文件 一般都是 index.php 加上 这几行代码就可以了 具体的参数可以根据需要去修改 header("Access-Control-Allow-Origin: *"); header(Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS); header(Access-Control-Allow-Heade…

C++11的一些特性

1、列表初始化&#xff0c;对内置类型和自定义类型都可以使用列表进行初始化——一切都可以用列表初始化 不要和初始化列表混了 std::initializer_list临时对象作为函数的参数&#xff0c;用来接收{}括起来的的初始化列表 容器中有用initializer_list作为参数的构造函数&…

MySQL多系统安装配置教程(Windows、Ubuntu、Centos)

专题目标 • 掌握在Windows下安装MySQL数据库 • 掌握在CentOS下安装MySQL数据库 • 掌握在Ubuntu下安装MySQL数据库 一、在Windows下安装MySQL数据库 • Windows下推荐使用安装程序进行安装 • 安装程序下载地址&#xff1a;https://dev.mysql.com/downloads/ 通过上面的安装…

关于 npm 更新镜像源问题

npm&#xff08;Node Package Manager&#xff09;&#xff0c;是一个NodeJS包管理和分发工具&#xff0c;已经成为了非官方的发布Node模块&#xff08;包&#xff09;的标准。&#xff09; 查看当前npm版本 npm -v 10.9.0 执行以下命令报错 npm install --registryhttp…

Netty篇(入门编程)

目录 一、Hello World 1. 目标 2. 服务器端 3. 客户端 4. 流程梳理 &#x1f4a1; 提示 5. 运行结果截图 二、Netty执行流程 1. 流程分析 2. 代码案例 2.1. 引入依赖 2.2. 服务端 服务端 服务端处理器 2.3. 客户端 客户端 客户端处理器 2.4. 代码截图 一、Hel…

文本语义分块、RAG 系统的分块难题:小型语言模型如何找到最佳断点

文本语义分块、RAG 系统的分块难题&#xff1a;小型语言模型如何找到最佳断点&#xff1f; 转自jina最新的关于文本语义分块的分享和模型 之前我们聊过RAG 里文档分块 (Chunking) 的挑战&#xff0c;也介绍了 迟分 (Late Chunking) 的概念&#xff0c;它可以在向量化的时候减…

大数据技术在金融风控中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 大数据技术在金融风控中的应用 大数据技术在金融风控中的应用 大数据技术在金融风控中的应用 引言 大数据技术概述 定义与原理 发…

小程序中引入下载到本地的iconfont字体图标加载不出来问题解决

我这个是uniapp项目,字体图标都是一样的,在vue项目中web端、uniapp运行到h5都没问题,但是运行到小程序加载不出来,报错如下: 不让用本地路径,所以我们要转为base64编码,这里给大家提供一个工具,它可以把本地字体文件转为base64:transfonter 进入官网后,第一步: …

MYSQL隔离性原理——MVCC

表的隐藏字段 表的列包含用户自定义的列和由系统自动创建的隐藏字段。我们介绍3个隐藏字段&#xff0c;不理解也没有关系&#xff0c;理解后面的undo log就懂了&#xff1a; DB_TRX_ID &#xff1a;6 byte&#xff0c;最近修改( 修改/插入 )事务ID&#xff0c;记录创建这条记…

vue3 + element-plus 的 upload + axios + django 文件上传并保存

之前在网上搜了好多教程&#xff0c;一直没有找到合适自己的&#xff0c;要么只有前端部分没有后端&#xff0c;要么就是写的不是很明白。所以还得靠自己摸索出来后&#xff0c;来此记录一下整个过程。 其实就是不要用默认的 action&#xff0c;要手动实现上传方式 http-reque…

【C++课程学习】:二叉搜索树

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 二叉树搜索树的概念&#xff1a; 节点的结构&#xff1a; ⚽️结构&#xff1a; ⚽️ 构造函数&…

Axure是什么软件?全方位解读助力设计入门

在产品设计和开发领域&#xff0c;Axure是一款大名鼎鼎且功能强大的软件&#xff0c;它为专业人士和团队提供了卓越的设计支持&#xff0c;帮助他们将创意转化为实际可操作的产品原型。 一、Axure 的基本介绍 Axure是一款专业的原型设计工具&#xff0c;主要用于创建交互式的…

java里面使用groovy案例+详解

场景&#xff1a; 最近有一个计算商品运费的&#xff0c;如果商品的数量大于快递公司设置的数量 10 那么超出部分也需要计算额外运费&#xff0c;那么这些计算过程代码我能不能不在java里面写呢&#xff0c;用一种可配置化的方式来根据不同的传参计算出运费&#xff1f; 页面传…

单体架构 IM 系统之核心业务功能实现

在上一篇技术短文&#xff08;单体架构的 IM 系统设计&#xff09;中&#xff0c;我们讨论了在 “用户规模小、开发人员少、开发时间短” 的业务背景下&#xff0c;采取 “怎么简单怎么做&#xff0c;怎么快怎么来” 的研发策略&#xff0c;于是设计了 单体架构的IM系统&#x…

Linux部署nginx访问文件403

问题描述&#xff1a;在linux服务器上通过nginx部署&#xff0c;访问文件403 新配置了一个用户来部署服务&#xff0c;将部署文件更新到原有目录下&#xff0c;结果nginx访问403 原因&#xff1a;没有配置文件的读写权限&#xff0c;默认不可读写&#xff0c;nginx无法访问到文…

解决 C/C++ 中 “invalid use of incomplete type” 编译错误

解决 C/C++ 中 “invalid use of incomplete type” 编译错误 一、错误原因二、常见场景三、解决方法四、最佳实践五、总结在 C 和 C++ 编程中,invalid use of incomplete type 错误通常发生在尝试使用一个未完全定义的类型时。这个错误表明编译器在当前上下文中没有足够的信息…