AVLTree深度剖析(单旋)

前言

二叉树搜索树是存在一定的缺陷问题的,当我们要插入的数据是有序,或者说接近于有序,,二叉搜索树及有可能退化为单支树,查找元素相当于在顺序表当中搜索元素,效率低下

---------------------------------------------------------------------------------------------------------------------------------

AVL树的概念

解决上述问题的方法是两位俄罗斯科学家发明的: 当向二叉搜索树当中插入新节点后,如果能保证每个节点的左右子树高度差的绝对值不超过1(超过对树当中的节点做调整),降低树的高度,从而减少平均搜索长度

一颗AVL树或者是空树,或者是具有以下性质的二叉搜索树:

1.它是左右子树都是AVL树

2.左右子树高度之差(简称平衡因子)的绝对值不超过(-1   /   0    /1)  平衡因子:右子树的高度-左子树的高度

 如果一颗二叉搜索树是高度平衡的,它就是AVL树,如果它有n个节点,其高度可保持在log_2(N),那么搜索的时间复杂度以2为底N的对数!!!

log以2为底n的对数是查找效率非常高的了,假设将我们全中国人口14亿人的数据保存在这样的一颗树当中,那么只需要查找31次,最多31次,高度次,是非常恐怖的!!!

-----------------------------------------------------------------------------------------------------------------------

实现AVL树

 为何我们在这里使用三叉链呢??

当我插入一个新节点之后,这棵树还是不是平衡树,我们就看高度差,不过呢平衡因子就是高度差的一个结果,在插入新节点之后我们得想办法更新平衡因子,更新的是祖先的平衡因子

 ----------------------------------------------------------------------------------------------------------------------

insert插入的实现

按照我们以前的搜索树的insert,到这一步也就结束了,但是我们这里插入之后,我们得控制平衡

有可能插入之后还是平衡的,也可能插入之后,不平衡了

我们在判断这颗树,或者子树是否平衡时,是通过平衡因子判断的,所以在判断是否平衡之前,得先更新平衡因子

更新平衡因子的规则:

1.新增在右,parent->_bf++    ,新增在左,parent->_bf--;

 2.更新后,parent->_bf  == 1或者-1  ,说明parent插入之前的平衡因子是0,说明左右子树高度相等,插入有一边高,parent的高度变了,继续往上更新

更新后,parent->_bf == 1   or  -1   ,  1代表右边高, -1代表左边高  ,这里要不要继续往上更新平衡因子的因素取决于,parent子树的高度是否变化,parent的平衡因子变为-1或者1,高度肯定的变了,为什么呢? 因为++  或者 -- 之后变为 -1 或者1  说明在不插入新节点之前是左右子树高度是一样的

我们在这里有没有可能parent的平衡因子是  2或者  -2   ,加加 减减之后变为 1或者-1 呢??肯定是不可能的,如果之前是2或者-2的画早就不平衡了,之前就应该做调整

3.更新后,parent->_bf ==0  ,说明parent插入之前的平衡因子  -1   或者  1  加加或者减减一下,说明左右子树一边高一边低,插入之后,两边一样高,说明插入填上了矮的那一边,parent所在的子树高度不变,不需要继续向上更新

 4.更新后,parent->_bf == 2或者-2  ,说明parent插入前的平衡因子是  1or  -1  ,说明在插入之前已经是平衡的临界值了,现在插入变成2或者-2  ,说明打破平衡,parent所在的子树,需要进行旋转处理

5.更新后,parent->_bf >2   or   parent->_bf < -2 ,不可能,如果存在则说明插入之前就不是AVL树,那需要去检查之前的操作问题

 此时这颗树,并没有发生旋转,但是快要发生旋转了,倾向于旋转了,好几个节点的平衡值都在临界值。

 -------------------------------------------------------------------------------------------------------------

我们现在写更新平衡因子的代码  -->   最坏的情况就是不断更新,更新到根节点,也可能中间就停止了

 接下来就是要处理我们的旋转问题了

在这里我们需要想办法去处理,无论是整颗树,还是子树

我们在这里处理的原则 :

1.旋转成平衡树

2.保持搜索树的规则

 对上面的情况网上有人做了归类

左单旋

 当h==2的时候,就已经有36种情况了

当h==3时,情况就更多了

如果我们要列举这里的情况,是无穷无尽的,但是对于上面情况当中的哪一种,我们的处理动作都是一样的

所以插入的时间复杂度是  高度次更新平衡因子+旋转的时间复杂度(O(1))

--------------------------------------------------------------------------------------------------------------------------

右单旋

a、b、c是h大于等于0的平衡树

 

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

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

相关文章

Python对Excel不同的行分别复制不同的次数

本文介绍基于Python语言&#xff0c;读取Excel表格文件数据&#xff0c;并将其中符合我们特定要求的那一行加以复制指定的次数&#xff0c;而不符合要求的那一行则不复制&#xff1b;并将所得结果保存为新的Excel表格文件的方法。 这里需要说明&#xff0c;在我们之前的文章Pyt…

【C++】list的使用及底层实现原理

本篇文章对list的使用进行了举例讲解。同时也对底层实现进行了讲解。底层的实现关键在于迭代器的实现。希望本篇文章会对你有所帮助。 文章目录 一、list的使用 1、1 list的介绍 1、2 list的使用 1、2、1 list的常规使用 1、2、2 list的sort讲解 二、list的底层实现 2、1 初构…

等保测评包过是真的吗?安全吗?

最近有小伙伴在问&#xff0c;等保测评包过是真的吗&#xff1f;安全吗&#xff1f;哪位大哥来解答一下&#xff1f; 等保测评包过是真的吗&#xff1f;安全吗&#xff1f; 【回答】&#xff1a;等级保护采用备案与测评机制&#xff0c;而非认证机制&#xff0c;因此不存在“包…

【C语言】杨氏矩阵中寻找元素

题目名称&#xff1a; 杨氏矩阵 题目内容&#xff1a; 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从下到上递增的&#xff08;杨氏矩阵的定义&#xff09;&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 形如这样的矩阵就是杨氏…

Windows bat隐藏运行窗口的几种方案

文章目录 一、背景二、测试数据三、隐藏bat运行窗口方案1. 使用VBScript脚本2. 使用mshta调用js或vbs脚本3. 将bat编译为exe程序4. 使用任务计划程序 一、背景 有些程序在执行批处理脚本时&#xff0c;可能会看到dos窗口&#xff0c;或者看到窗口一闪而过。如果批处理脚本执行…

【AUTOSAR】:车载以太网

车载以太网 References参考文献车载以太网的物理连接MACPHYPHY的主从关系100BASE-T1回音消除车载以太网的应用层协议References参考文献 汽车软件通信中间件SOME/IP简述100BASE-T1以太网:汽车网络的发展车载以太网的物理连接 MAC MAC(Media Access Control介质访问)一般集成…

【VirtualBox】安装 VirtualBox 提示 needsthe Microsoft Visual C++ 2019

概述 一个好的文章能够帮助开发者完成更便捷、更快速的开发。书山有路勤为径&#xff0c;学海无涯苦作舟。我是秋知叶i、期望每一个阅读了我的文章的开发者都能够有所成长。 一、开发环境 开发环境&#xff1a;windows10虚拟机&#xff1a;VirtualBox 7.0.8 二、报错 ubun…

23.JavaWeb-集群+Nginx+JMeter

1.集群概念 平时用的服务是的并发量是有限的&#xff0c;像tomcat只有不到500的并发量&#xff0c;不能满足高并发的需求&#xff0c;因此就采用了集群的方法&#xff0c;用多个服务器 当用户请求集群系统时&#xff0c;集群给用户的感觉就是一个单一独立的服务器&#xff0c;而…

基于STM32 ARM+FPGA伺服控制系统(二)软件及FPGA设计

完整的伺服系统所包含的模块比较多&#xff0c;因此无法逐一详细介绍&#xff0c;所以本章着重介绍 设计难度较高的 FPGA 部分并简单介绍 ARM 端的工作流程。 FPGA 部分主要有 FOC 算法、电流采样算法及编码器采样算法&#xff0c;是整个控制系统的基础&#xff0c;直接…

ELK-日志服务【redis-配置使用】

目录 环境 【1】redis配置 【2】filebeat配置 【3】对接logstash配置 【4】验证 【5】安全配置&#xff1a;第一种&#xff1a;kibana-nginx访问控制 【6】第二种&#xff1a;在ES-主节点-配置TLS 【7】kibana配置密码 【8】logstash添加用户密码 环境 es-01,kibana 1…

ChatGPT 最佳实践指南之:系统地测试变化

Test changes systematically 系统地测试变化 Improving performance is easier if you can measure it. In some cases a modification to a prompt will achieve better performance on a few isolated examples but lead to worse overall performance on a more representa…

C++类和对象——类的基础

目录 类的引入类的定义类的访问限定符和封装对象的实例化类对象的大小this指针 类的引入 在C语言中&#xff0c;结构体中只能定义变量 但是在C中&#xff0c;结构体不仅可以定义变量&#xff0c;还可以定义函数 下面就是C中的一个结构体&#xff1a; struct Stack {void init(…