C++数据结构之平衡二叉搜索树(一)——AVL的实现(zig-zag/左右双旋/3+4重构)

news2024/10/2 12:28:28

目录

  • 00.BBST——平衡二叉搜索树
  • 01.AVL树
  • 02.AVL的插入
      • 2.1单旋——zig 与 zag
      • 2.2插入节点后的单旋实例
      • 2.3手玩小样例
      • 2.4双旋实例
      • 2.5小结
  • 03.AVL的删除
      • 3.1单旋删除
      • 3.2双旋删除
      • 3.3小结
  • 04.3+4重构
  • 05.综合评价AVL
      • 5.1优点
      • 5.2缺点

00.BBST——平衡二叉搜索树

本文是介绍众多平衡二叉搜索树(BBST)的第一篇——介绍AVL树。故先来引入BBST的概念。由于上一篇介绍的二叉搜索树(BST)在极度退化的情况下,十分不平衡,不平衡到只朝一侧偏,成为一条链表,复杂度可达 O ( n ) O(n) O(n),所以我们要在“平衡”方面做一些约束,以防我们的树结构退化得那么严重。

具体来说,含 n n n个节点,高度为 h h h的BST,若满足 h = O ( l o g 2 n ) h=O(log_2 n) h=O(log2n),则称为称为平衡二叉搜索树。

01.AVL树

AVL树是一种BBST(稍后会证明)。它约束自己是否平衡,主要靠一个指标——平衡因子。定义:平衡因子=左子树高度-右子树高度。如果满足 − 2 < 全部平衡因子 < 2 -2<全部平衡因子<2 2<全部平衡因子<2,则该AVL树处于平衡状态;否则,需要靠一系列措施,将其恢复平衡。

首先先证明AVL树满足BBST的要求,即 h = O ( l o g 2 n ) h=O(log_2 n) h=O(log2n)(下式)。我们可转而证明n=Ω(Φh)(即,AVL的节点数不会太少)
在这里插入图片描述

结论:高度为h的AVL Tree 至少有 fib((h+3)-1 个节点
证明:
在这里插入图片描述

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

02.AVL的插入

插入一个节点会导致一串祖先的失衡,删除一个节点至多导致一个祖先失衡。但是,通过后续代码就可发现,删除节点比插入节点复杂的多。原因是,插入节点只要调整好了一处,这条路径上的所有祖先都可平衡,复杂度是O(1)。而删除节点是,调整好了一处平衡,另一处就会不平衡,自下而上层层调整,复杂度是O(n)

2.1单旋——zig 与 zag

zig 与 zag 分别对应右单旋和左单旋。单旋的操作改变的是两个节点的相对位置。改变的是三条线:一上一下一子树。新树根上行指向原根,新树根原子树给到原根。如下图,V到Y那去,Y到C那去。

在这里插入图片描述

2.2插入节点后的单旋实例

在下图处添加一个节点,自上而下更新高度(或平衡因子),g会率先进入不平衡状态。观察g,p,v呈一条线,而非“之”字,所以用单旋调整(之字形对应双旋)。具体来说,对g左单旋。
在这里插入图片描述

2.3手玩小样例

例题:将1,2,3,4,5,6依次插入空的AVL Tree,最终AVL Tree长成什么样?

过程:
首先正常插入1,2;插入3时,1是第一个发现不平衡的节点,zag(1),即对1进行左单旋,成功解决;正常插入4
在这里插入图片描述

插入5时,3是第一个发现不平衡的节点,zag(3),即对3进行左单旋,成功解决
在这里插入图片描述
插入6时,2是第一个发现不平衡的节点,zag(2),即对2进行左单旋,成功解决
在这里插入图片描述

2.4双旋实例

双旋的操作改变的是三个节点的相对位置。分为两种情况——zig-zag与zag-zig。

在下图处添加一个节点,自上而下更新高度(或平衡因子),g会率先进入不平衡状态。观察g,p,v呈“之”字,所以用双旋。具体来说,先zig§,再zag(g).
在这里插入图片描述

2.5小结

AVL树中插入节点引发失衡,经旋转调整后重新平衡,此时包含节点g,p,v的子树高度是不变的子树高度复原,更高祖先也必平衡,全树复衡。故在AVL树中修正插入节点引发的失衡不会出现失衡传播。

03.AVL的删除

删除一个节点至多导致一个祖先失衡。

3.1单旋删除

在这里插入图片描述

3.2双旋删除

在这里插入图片描述

3.3小结

AVL树中删除节点引发失衡,经旋转调整后重新平衡,此时包含节点g,p,v的子树高度有可能不变也有可能减小1,故在AVL树中修正删除节点引发的失衡有可能出现失衡传播。

04.3+4重构

通过观察以上插入和删除的结果示意图,发现结构是一样的——三个节点按顺序呈三角形,四个子树按原来的顺序分别挂在两个孩子节点的下边。(如下图)
在这里插入图片描述

那我们就不必关注具体的技巧了,而是将三个节点和四个子树拆开,像暴力组装魔方那样(先拆散)拼上。

05.综合评价AVL

5.1优点

  1. 查找、插入、删除,最坏时间复杂度为 O ( l o g n ) O(logn) O(logn)
  2. O ( n ) O(n) O(n)的存储空间

5.2缺点

  1. 需要额外维护高度或平衡因子这一指标(后续Splay Tree可改善这一问题)
  2. 删除操作后,最多需旋转 Ω ( l o g n ) \Omega(logn) Ω(logn)
  3. 单次动态调整后,全树拓扑结构的变化量可能高达 Ω ( l o g n ) \Omega(logn) Ω(logn) (RedBlack Tree可缩到 O ( 1 ) O(1) O(1)

谢谢观看~

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

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

相关文章

Sui的赞助交易(gas代付),打开Web2用户丝滑使用Web3之路

Sui Move包括一个功能&#xff0c;允许开发者为其应用程序的一些或全部交易支付gas费&#xff0c;消除了用户在进入Web3时面临的一个最大障碍。在Web3网络中&#xff0c;通常用户需要支付所谓的 gas费才能使用应用程序。Sui的赞助交易功能为愿意采用的开发者消除了这种阻碍。 …

仓库管理系统有哪些功能,如何对仓库进行有效管理

阅读本文&#xff0c;您可以了解&#xff1a;1、仓库管理系统有哪些功能&#xff1b;2、如何对仓库进行有效管理。 仓库是制造业的开端&#xff0c;原材料的领料开始。企业的仓库管理是涉及企业生产、企业资金流和企业的经营风险的关键环节。在众多的工业企业、制造型企业、贸…

都市信息供求网servlet+jsp新闻广告出售java源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 都市信息供求网servletjsp 系统1权限&#xff1a;管理…

怎么做自动化测试?8年测试老鸟自动化测试总结,史上最全...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、为什么做自动化…

AutoML工具-AutoGluon

1、简介 AutoGluon是AutoML的自动化工具&#xff0c;涉及方面有图像、文本、时间序列和表格式数据。 2、入门 2.1 安装 pip install autogluon 2.2 使用 &#xff08;1&#xff09;Tabular&#xff08;解释是表格式数据&#xff0c;不知道对不对&#xff09; 两个函数Ta…

Vue使用QuillEditor富文本编辑器问题记录

1.内容绑定的问题 绑定内容要使用 v-model:content"xxx" 的形式。 2.设置字体字号 字体以及字号大小的设置需要先注册。 <script> import { QuillEditor,Quill } from vueup/vue-quill import vueup/vue-quill/dist/vue-quill.snow.css; // 设置字体大小 c…

认识聚类算法【机器学习必学】

什么是聚类算法? 聚类算法是一种典型的无监督学习算法&#xff0c;主要用于将相似的样本自动归到一个类别中。 在聚类算法中根据样本之间的相似性&#xff0c;将样本划分到不同的类别中&#xff0c;对于不同的相似度计算方法&#xff0c;会得到不同的聚类结果&#xff0c;常…

为代码生成一个良好可读的API文档-Doxygen简单实战

需求&#xff1f;为什么要有API文档 在代码开发过程中&#xff0c;我们会发现有这样的情况&#xff0c;其他团队的代码和自己团队的代码相异甚大&#xff0c;如果没有一个统一规范的文档来对接&#xff0c;会造成很多交流沟通上的不便&#xff0c;但我们又不想浪费时间去边写说…

探索产品项目管理软件的种类及功能

随着科技的不断发展&#xff0c;越来越多的企业开始重视产品项目管理的重要性。产品项目管理软件作为一种有效的工具&#xff0c;可以帮助企业更好地规划、执行和控制项目&#xff0c;提高项目的成功率。本文将分为两部分&#xff0c;分别介绍产品项目管理软件的功能以及一些知…

微信认证申请流程(其他组织)

第一步&#xff1a;登录微信公众平台->设置->微信认证->开通 第二步&#xff1a;同意协议&#xff1a;签署《微信公众平台认证服务协议》 第三步&#xff1a;验证管理员 第三步&#xff1a;选择认证类型及填写认证资料 选择认证类型及上传申请公函 其他组织资质信息 …

制作分班查询系统必备软件,轻松解决分班查询烦恼

常用的分班查询系统制作工具有以下几种&#xff1a; 1. 编程语言和框架&#xff1a;使用编程语言和相关的框架&#xff0c;如Java、Python、PHP等&#xff0c;可以自行开发分班查询系统。这种方式可以根据学校的具体需求进行定制开发&#xff0c;灵活性较高。 2. 数据库管理系…

管理类联考——逻辑——形式逻辑——汇总篇——专业术语

专业术语 专业术语 日常描述 符号化 符号表达 表达含义 常见标志词充分条件假言判断如果P&#xff0c;那么Q→P→Q如果P为真&#xff0c;则Q一定为真&#xff1b;如果Q为假&#xff0c;那么P一定为假。也就是P→Q和┐Q→┐P一定为真。如果P&#xff0c;那么Q&#xff1b;只要P&…

51单片机(普中HC6800-EM3 V3.0)实验例程软件分析 实验三 LED流水灯

目录 前言 一、原理图及知识点介绍 二、代码分析 知识点五&#xff1a;#include 中的库函数解析 _crol_&#xff0c;_irol_&#xff0c;_lrol_ _cror_&#xff0c;_iror_&#xff0c;_lror_ _nop_ _testbit_ 前言 第一个实验:51单片机&#xff08;普中HC6800-EM3 V3.0…

OpenLayers入门,OpenLayers使用fetch加载并显示TopoJson格式区划边界数据并叠加文字标注,动态创建要素样式

专栏目录: OpenLayers入门教程汇总目录 前言 上一章中已经说明了TopoJson格式数据,《OpenLayers入门,OpenLayers加载TopoJson数据,使用行政区划边界作为示例》,大家应该都已经有所了解。 本章在上一章基础上改用fetch加载TopoJson格式数据,并手动解析数据为Feature要素…

学习单片机的秘诀:实践与坚持

在学习单片机时&#xff0c;将实践与学习结合起来是一个很好的方法。不要一上来就死磕指令和名词&#xff0c;而是边学边做实验&#xff0c;循序渐进地理解和应用指令。通过实验&#xff0c;你能亲身感受到指令的控制效果&#xff0c;增强对单片机的理解和兴趣。 学习单片机不…

LeetCode344.反转字符串

344.反转字符串 题目描述 解题思路 这是字符串专题的第一题 在之前反转链表的题目中&#xff0c;我们使用了双指针法来进行反转链表 这道题同样的&#xff0c;也使用双指针&#xff0c;对于字符串的反转&#xff0c;比链表更为简单 因为字符串本质上是一种数组&#xff0c…

Paleobotany——北美中生代-新生代化石植物总目(Paleobotanical card search)

北美中生代-新生代化石植物总目&#xff08;Paleobotanical card search&#xff09; 总览1. 介绍2. 历史3. 内容 用户手册&#xff08;卡片内容解读&#xff09;示例卡片组成CIC编号的详细解读年代编码解读 卡片检索 总览 了解学习使用由耶鲁皮博迪自然历史博物馆&#xff08…

印度想建设6G强国,是梦想还是幻想?

拥有14亿人口的印度&#xff0c;也是一个充满梦想与野心的国家&#xff0c;印度一直在努力追赶科技的发展&#xff0c;尤其是通信领域。印度目标是在2030年成为6G强国&#xff0c;然而其计划与现实之间还存在着巨大的鸿沟。 本报告分别从印度互联网普及率、城乡差异、用户性别、…

MySql006——检索数据:基础select语句

在《MySql003——结构化查询语言SQL基础知识》中&#xff0c;我们学习了有关SQL的基础知识&#xff0c;也知道SQL中查询语句select使用最为频繁。 它的用途是从一个或多个表中检索信息。为了使用SELECT检索表数据&#xff0c;必须至少给出两条信息——想选择什么&#xff0c;以…

AOP获取切点表达式中注解的属性

文章目录 1、获取Cacheable注解的属性2、获取自定义注解的属性 1、获取Cacheable注解的属性 有个小需求&#xff0c;要在日志中打印支持redis缓存的方法的相关信息&#xff0c;这里切点表达式动词用annotation&#xff0c;后面跟Cacheable注解 Component Aspect Slf4j public…