AVL树的插入

news/2025/1/13 19:45:41/文章来源:https://www.cnblogs.com/fufufuf/p/18669306

关于AVL树的插入,其实是一个比较复杂的问题,主要是在于他对于“旋转”这一概念,对于这一概念其实我感觉很多博主讲的都不是很明白,包括CHATGPT,也试了,但是也没有比较清楚的解释,他们主要集中在一种比较简单的情况,即没有任何子树的情况,如下所示



对于这种最基本的平衡维护,确实不是一件困难的事情,这个可以作为一种技巧,来帮助我们快速的来去得到答案。所以在这里,我会先从最基本的情况来去讲解这里是怎么个操作的流程,这里会不用“旋转”这一概念来解释平衡的维护,而是一种更加简单易懂的方式来讲解。

(注  本次的博客会在发布之后补充上代码,现在不会添加代码,只是会提供相关的概念)

其实个人觉得看到不错的是这个,推荐一下便于大家学习https://www.hello-algo.com/chapter_tree/avl_tree/#2_1

OK。可恶的作者终于把他的废话说完了,现在开始要说内容了。

首先是对于这里的基本情况。

如下所示

可以看到是有四种情况,这里即是插入节点后失衡的四种情况。对于这四种情况,我们可以对他们做一个分类,分为直线型和弯线型。

为什么叫直线型和弯线型,其实在这里是非常明显的(这里当然很明显,但是对于实际的节点插入来说就不是特别明显了),我们将插入的节点向上回溯,然后一直到第一个失衡点,这样子来看,到达第一个失衡点之后,向下往插入点的方向标记三个单位,这个三个点就是接下来要主要操作的三个点了。

如下所示,

可以看到如上面的图片所示,可以知道,他为什么叫直线型和弯线型。那么接下来,就是如何对他们做操作呢,其实也是很简单的。

对于直线型,我们要做的就是把他掰弯,为了方便起见,我们将这三个点由上到下分别叫做爷爷,父亲,儿子。那么要做的是把爷爷弯折至和儿子一个高度,让后再将父亲给连接上。

对于弯线型,则是不一样,我们要先将它弄直,然后再像直线型一样操作。对于再将弯线型弄直的过程中,由于他是一个二叉树,所以要将父亲和儿子的值给交换一下,这样子才可以让其维持二叉树的特点。

那么这种最基本的情况讲完了,但是这并不足以应付一些复杂的情况,如果说存在子树的话,那么怎么去移动父亲,儿子,爷爷三个点的子树就成为了问题。

那么如下所示

对于这样子一个二叉树,我应该怎么去维护他的平衡性。可以按照如下的操作。

首先我们要先找到他的不平衡点,我们去依次标记他的子树的大小,如下所示

可以知道当前的为直线型,爷爷,父亲,儿子分别为4,7,15三个点,那么由于是直线型,那么父亲必然是要作为接下来的新根节点,但是问题是此时,由于他是在中间位置,如果我直接去做弯折的操作,就会导致他的子树无法处理(总不能直接变成三叉树吧),所以这个时候,我需要做的是对他的子树进行转移。

如何转移他的子树呢,对于由于此时爷爷节点在下移了之后,他的位置有一个子树的位置是空了,所以在这里可以把子树转移到他的爷爷节点下面,转移之后,如下所示

实际上,我们就是将节点转移到了爷爷上面,并且把父亲作为了新的根节点。

那么对于有子树的弯折型,又应该怎么处理呢,可以参考如下的例子。在这里,已经标记好了弯折点。

在这里,接下来要做的就是去首先将它给掰直,在掰直的过程中,可以发现由于16的存在,影响了掰直,所以在这里的处理措施是将将7移动到与6连接的地方,在这之后,就是将15节点移动下来,并将14节点拼接到15节点上,这样,就完成了一次移动,完成后的结果如下所示。
之后,我们可以看到他接下来就可以弄弯了。

这样子,我们就可以实现对他的平衡的维护了。

最后总结一下吧。

1.对于直线型,我们要做的是将它儿子的那个不在线上的子树给他的父亲节点,这样子就可以完成平衡的维护

2.对于弯线型,则可以去将其儿子的子树给到父亲节点,然后将儿子放在中间位置,在这之后,就是做和直线型一样的操作。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【事件分析】20250112-Usual 赎回机制调整事件

背景信息 https://docs.usual.money/ Usual 是一个聚合 RWA 的稳定币发行协议,经济模型中存在三种代币:USD0:Usual 发行的稳定币。 USD0++:USD0++ 是 USD0 的质押版本,为期4年,可获得 USUAL 代币奖励。 USUAL:Usual 协议的治理代币。事发缘由 https://usual.money/blog/…

痞子衡嵌入式:我评上了2024年度电子星球(eestar)最强大脑

今天收到了「电源网旗下电子星球」 颁发的 2024 年度最强大脑奖牌,这是电子星球第二年给痞子衡颁奖了。这个奖牌设计得非常用心,区别于去年奖牌只能捧在手上,今年痞子衡可以把奖牌挂脖子上出去拉风了。从23年8月开始,电子星球小编每个工作日会转发一篇痞子衡的技术原创文章…

React源码解析(1): JSX语法与react项目渲染过程

好家伙0.前言 由于工作的需要,我不得不入手了react的全家桶,曾经我的主要技术栈是vue。 从vue转到react,一开始我感到非常不适应,jsx的语法的不了解,react hooks的使用方式,react路由的配置。。。这一度让我十分难受 但在熟悉一段时间后,我逐渐领略到react的魅力,灵活的…

痞子衡嵌入式:我拿到了2024年度电子星球(eestar)最强大脑

今天收到了「电源网旗下电子星球」 颁发的 2024 年度最强大脑奖牌,这是电子星球第二年给痞子衡颁奖了。这个奖牌设计得非常用心,区别于去年奖牌只能捧在手上,今年痞子衡可以把奖牌挂脖子上出去拉风了。从23年8月开始,电子星球小编每个工作日会转发一篇痞子衡的技术原创文章…

使用嗅探大师(sniff master)进行手机端iOS抓包的配置步骤

一个强大的iOS端抓包工具,嗅探大师(sniff master),比市面上的一些抓包工具操作更简单。之前做网页端开发的时候找到一个抓包工具,嗅探大师,当时用来在Windows上面进行抓包,发现他在手机端iOS方面的抓包更为强大,而且还有HTTPS暴力抓包,无需设置代理,无需越狱,无需ro…

keycloak~巧用client-scope实现token字段和userinfo接口的授权

keycloak中的client-scope允许你为每个客户端分配scope,而scope就是授权范围,它直接影响了token中的内容,及userinfo端点可以获取到的用户信息,这块我们可以通过自定义scope/mapper,来实现粒度的控制,并且这个mapper可以控制添加到token,或者添加到userinfo端点,这两块…

.NET Core 委托原理解析

.NET Core 委托原理解析 在 .NET Core 中,委托(Delegate)是一种类型安全的函数指针,它允许你将方法作为参数传递给其他方法,或者将方法存储在变量中以便稍后调用。委托在事件处理、回调机制以及异步编程中非常有用。理解委托的运行原理对于掌握 .NET Core 的高级编程技巧至…

Ellyn-Golang调用级覆盖率&方法调用链插桩采集方案

在应用程序并行执行的情况下,精确获取单个用例、流量、单元测试走过的方法链(有向图)、出入参数、行覆盖等运行时数据,经过一定的加工之后,应用在覆盖率、影响面评估、流量观测、精准测试、流量回放、风险分析等研发效能相关场景。词语解释Ellyn要解决什么问题? 在应用程…

[megatron代码阅读] 1. 初始化和组网

以pretrain_gpt.py为例, 看megatron的整体逻辑. 本章主要包括megatron初始化相关逻辑, 核心函数为initialize_megatron, setup_model_and_optimizer两个 initialize_megatron parse_args 从argparse中直接读取超参数配置. 如学习率, 正则化等. 从环境变量中获取rank等 load_arg…

巧用VTable打造炫酷金字塔图表

在数据分析和可视化领域,表格是展示数据直观、有效的方式之一。今天,就让我们来探索如何利用VTable这个强大的表格组件,制作出既美观又富有信息量的金字塔图表,以及深入了解VTable中各种单元格类型的使用方法,让你的表格也能“绘”出精彩图表!在数据分析和可视化领域,表…

基于 Performace 分析事件循环

我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。本文作者:千寻什么是事件循环? 我们为什么需要事件循环?对于 JavaScript 是一门单线程语言我们是肯定的,JavaScript 单线程的特性保证了渲…

万字图文:SaaS业务架构、价值流、业务能力、业务流程、业务对象、组织架构

大家好,我是汤师爷~ 本文为读者提供一个SaaS业务架构的系统性框架,探讨业务架构分析的核心要素,帮助SaaS企业深入剖析目标客户的业务模式,全面理解他们的业务架构。 无论你是SaaS创业者、产品经理还是架构师,本文内容都将为你的系统设计和决策提供帮助。 1 目标与步骤 Saa…