learn C++ NO.21——AVL树

news2024/10/9 9:42:57

简单介绍一下AVL树

AVL树是一种自平衡的二叉搜索树(Balanced Binary Search Tree, BBST),由俄罗斯数学家G. M. Adelson-Velsky和E. M. Landis在1962年发明,因此以其名字首字母命名。AVL树通过保持任何节点的两个子树的高度最大差别为1来确保树的平衡,这种平衡性使得AVL树在插入、删除和查找操作中具有较好的性能。这里我讲解的是以引入平衡因子的AVL树的模拟实现。平衡因子 = 左子树高度 - 右子树高度。

AVL树为什么不能做到绝对平衡呢?因为实际使用中,数据可能是一次一次插入的。这样导致了没有办法维持绝对平衡的结构。

AVL的增删改查的时间复杂度是O(lgN),它相较于二叉搜索树来说,通过平衡树的高度来提高了时间复杂度的上限。

插入接口的模拟实现

在实现insert之前,简单把AVL树的基本模子整起来
在这里插入图片描述

下面正式介绍insert接口。这里我先将二叉搜索树的插入接口的逻辑部分先写出来。
在这里插入图片描述
接下来重点介绍一下引入平衡因子以维持AVL树的平衡特性。因为平衡因子 = 右子树高度 - 左子树高度。

所以,当新节点插入在左边时,新节点的父亲节点的平衡因子–。当新节点插入在右边时,新节点的父亲节点的平衡因子++。

如果更新完父亲节点的平衡因子后,恰好父亲的平衡因子等于0,此时,说明parent所在的子树的高度不变, 不会再影响祖先, 不用再继续沿着到root的路经往上更新。插入结束,直接返回true。

在这里插入图片描述
如果此时更新完平衡因子后,父亲节点的平衡因子为1或-1时,仍然需要向上更新祖先节点的平衡因子。因为可能祖先的平衡因子的绝对值已经为2了。此时,继续向上更新平衡因子。
在这里插入图片描述

更新后parent平衡因子 ==2 or -2, 说明parent所在的子树的高度变化且不平衡, 对parent所在子树进行旋转, 让他平衡。然后插入结束

在这里插入图片描述

还有一个比较特殊的边界情况,当更新平衡因子更新到根节点时,插入结束。

在这里插入图片描述
接下来介绍旋转部分的内容。
首先介绍一下左单旋转。
在这里插入图片描述

通过上图可以看到,左单旋转的主要实现逻辑就是,将cur的左子树连接到parent的右子树,然后,将parent连接到cur的左子树。然后修改cur、parent、curLeft的_parent。最后将平衡因子修改成0。

具体的细节有需要考虑curLeft是否为空,以及parent->_parent是否为空的问题。以及需要让cur连接parent->_parent。

左单旋参考代码如下
在这里插入图片描述

再来看右单旋的实现
在这里插入图片描述

通过上图可以看到,右单旋转的主要实现逻辑就是,将cur的右子树连接到parent的左子树,然后,将parent连接到cur的右子树。然后修改cur、parent、curLeft的_parent。最后将平衡因子修改成0。细节问题同左旋转一致,这里不做赘述。

右单旋参考代码如下
在这里插入图片描述

下面介绍一下右左单旋
在这里插入图片描述
我们需要先对90进行右单旋,让后对30进行左单旋。然后树的高度就平衡了
在这里插入图片描述

虽然左旋接口和右旋接口可以复用。但是左旋和右旋接口中,统一将平衡因子全部改为0,这不符合双旋后的平衡因子。修改平衡因子需要考虑三个情况。

情况一,新增节点的平衡因子为 0。那么此时将parent、cur和curLeft的平衡因子全部修改成0即可。
blog.csdnimg.cn/direct/5a8daa91eab3400f947a68aff2bac82c.png)
情况二,新节点插入在curleft的右子树诱发的双旋。双旋后,需要将parent的平衡因子修改成-1,cur和curleft的平衡因子为0。
在这里插入图片描述
情况三,新节点插入在curleft的左子树诱发的双旋。双旋后,需要将cur的平衡因子修改成1,parent和curleft的平衡因子为0。

在这里插入图片描述
右左双旋参考代码
在这里插入图片描述
左右双旋的情况如下
在这里插入图片描述
这里的更新平衡因子一样需要考虑三个情况,分别为当curright为新插入节点时,三个节点平衡因子都为0。以及当插入在b位置时 parent的平衡因子为 1, cur和curright平衡因子为0。 以及当插入在c位置时, parent和curright的平衡因子为0, cur的平衡因子为-1。

参考代码如下
在这里插入图片描述

完整insert接口参考代码如下
在这里插入图片描述

总结一下insert接口,就是在二叉搜索树的insert的基础上引入平衡因子以及旋转的概念。引入平衡因子为了让树的高度差绝对值小于2,这样让搜索树的结构的到保证。让增删改查效率为树的高度次,即O(lgN)。而旋转就是保证平衡因子能够保证高度差绝对值小于2的手段。旋转一共分为单旋和双旋。单旋分左单旋和右单旋,双旋分左右双旋和右左双旋。通过学习AVL树insert接口,可以感受到AVL树的高效性能以及性能高效背后的原因。

删除接口的介绍

删除接口的实现思路如下,首先,按照搜索树的规则进行节点的删除。然后,再删除节点位置向上更新平衡因子。最后,若平衡因子为2或者-2,进行相应旋转来平衡高度。

学习了插入接口,相应的删除接口也就很好理解它的原理。处于学习者的角度看,AVL树的结构理解了就行,并不是需要我们去造一个轮子。毕竟知识是无穷无尽的,咱的精力是 有限的。

总结

AVL树是一种复杂且性能强悍的数据结构。它通过平衡因子绝对值小于2来控制二叉搜索树的高度,以达到增删改查的高效。通过insert的模拟实现,明白了如何使用旋转操作保证AVL树的平衡因子绝对值小于2。当然,并不是所有的AVL树都是这么设计,不使用平衡因子也能够做到控制好树的绝对高度。但是,这么设计代码的可读性就没那么好了。

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

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

相关文章

养生健康:从日常细节中寻觅长寿之钥

养生健康:从日常细节中寻觅长寿之钥 在这个快节奏的时代,健康似乎成了一种奢侈品,但实则不然。养生之道,不在于繁复的仪式,而在于融入日常的点点滴滴。今天,就让我们一起探讨几个简单却至关重要的养生习惯…

N1从安卓盒子刷成armbian

Release Armbian_noble_save_2024.10 ophub/amlogic-s9xxx-armbian (github.com) armbian下载,这里要选择905d adb 下载地址 https://dl.google.com/android/repository/platform-tools-latest-windows.zip 提示信息 恩山无线论坛 使用usb image tool restet a…

Java项目实战II基于Java+Spring Boot+MySQL的高校学科竞赛平台

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着高等教…

【Vue】Vue 快速教程

Vue tutorial 参考:教程 | Vue.js (vuejs.org) 该教程需要前置知识:HTML, CSS, JavaScript 学习前置知识,你可以去 MDN Vue framework 是一个 JavaScript framework,以下简称 Vue,下面是它的特点 声明式渲染&#xff…

音频进阶学习三——离散时间信号与系统

文章目录 前言一、离散时间信号1.基本信号2.离散时间信号的分类3.离散时间信号的简单运算4.单位脉冲在运算中的作用 二、离散时间系统1.什么是离散时间系统2.离散系统的分类 总结 前言 前面博主介绍了信号中的连续时间信号和离散时间信号,数字信号也是离散时间信号…

1.一、MyBatis入门

一、MyBatis入门 我们做为后端程序开发人员,通常会使用Java程序来完成对数据库的操作。Java程序操作数据库,现在主流的方式是:Mybatis。 一、什么是MyBatis? MyBatis官网的解释: MyBatis 是一款优秀的持久层框架,它…

基于Zabbix进行服务器运行情况监测

文章目录 引言I Zabbix主要构成下载并安装Zabbix被监控主机安装zabbix agent创建被监控主机报警设置II 常见问题cannot use database "zabbix": its "users" table is empty (is this the Zabbix proxy database?)重置 Zabbix Web 界面密码Zabbix agent i…

【c++】初步了解类和对象2

1、类的作用域 类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。 如图,此时在类内声明了函数firstUniqChar(),在类外进行了函数体的具体定义。 但是却…

【成神之路】Ambari实战-050-UI-如何通过配置修改ambari样式

在Ambari中,通过自定义UI控件(Widget),你可以灵活调整配置项的展现形式,使其更符合实际需求。这篇文章将详细介绍各种控件的使用,并提供代码示例和实际应用场景,帮助你成为UI配置的行家&#xf…

国家发改委等部门划时间点:到2026年底基本建成国家数据标准体系

摘要 【国家发改委等部门划时间点:到2026年底基本建成国家数据标准体系】10月8日,国家发改委等部门联合印发《国家数据标准体系建设指南》。《建设指南》提出计划,到2026年底,基本建成国家数据标准体系,围绕数据流通利…

jmeter学习(7)beanshell

beanshell preprocessor 发送请求前执行 beanshell postprocessor 发送请求前执行 获取请求相关信息 String body sampler.getArguments().getArgument(0).getValue(); String url sampler.getPath(); 获取响应报文 String responseprev.getResponseDataAsString(); 获…

应急响应:LinuxWindows实战排查

目录 应急响应 介绍: 应急流程: 抑制阶段: 对于Linux,一些常见的排查命令: 对于Windows,常见的排查命令: Windows应急(一) Windows应急(二&#xff0…

C++ string类(超详细一次性讲解)(上)

1. 为什么学习string类? 1.1 C语言中的字符串 C语言中,字符串是以 \0 结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想&…

Python OpenCV精讲系列 - 三维重建深入理解(十七)

💖💖⚡️⚡️专栏:Python OpenCV精讲⚡️⚡️💖💖 本专栏聚焦于Python结合OpenCV库进行计算机视觉开发的专业教程。通过系统化的课程设计,从基础概念入手,逐步深入到图像处理、特征检测、物体识…

细菌实例分割系统源码&数据集分享

细菌实例分割系统源码&数据集分享 [yolov8-seg-EfficientFormerV2&yolov8-seg-SPPF-LSKA等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Glob…

系分-数据库总结

历年试题2024年05月试题 BCN范式,模式分解,触发器类型2023年05月试题 NoSQL基本特点,NoSQL对比,混合数据库2022年05月试题4 两段锁,事务并发,数据一致,本地事务发布20…

生命的最高境界(深度好文)?

予人玫瑰,手有余香。 生命的最高境界,就一个字:给。 初级的快乐,是放任;中级的快乐,是自律;高级的快乐,是给予。 予人玫瑰,手有余香。 学会“给”,是我们一…

PCL 表面曲率下采样

目录 一、概述二、代码三、结果 一、概述 通过表面曲率信息对点云进行采样&#xff0c;选择表面曲率约束下的代表性点。 二、代码 #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/features/normal_3d.h&g…

《Python 安装指南:开启编程之旅》

《Python 安装指南&#xff1a;开启编程之旅》 在当今数字化的时代&#xff0c;编程已经成为一项越来越重要的技能。而 Python 作为一种简洁、高效且功能强大的编程语言&#xff0c;受到了众多开发者的青睐。无论是数据科学、人工智能、Web 开发还是自动化脚本编写&#xff0c…

2024.10.8 作业+思维导图

优化登录框&#xff1a; 当用户点击取消按钮&#xff0c;弹出问题对话框&#xff0c;询问是否要确定退出登录&#xff0c;并提供两个按钮&#xff0c;yes|No&#xff0c;如果用户点击的Yes&#xff0c;则关闭对话框&#xff0c;如果用户点击的No&#xff0c;则继续登录 当用户点…