06-看图理解数据结构与算法系列(AVL树)
AVL树
AVL树,也称平衡二叉搜索树,AVL是其发明者姓名简写。AVL树属于树的一种,而且它也是一棵二叉搜索树,不同的是他通过一定机制能保证二叉搜索树的平衡,平衡的二叉搜索树的查询效率更高。
AVL树特点
- AVL树是一棵二叉搜索树。
- AVL树的左右子节点也是AVL树。
- AVL树拥有二叉搜索树的所有基本特点。
- 每个节点的左右子节点的高度之差的绝对值最多为1,即平衡因子为范围为[-1,1]。
图中红色数字表示对应节点的高度,可以看到同一层的节点高度差都没有超过1。
二叉搜索树的平衡
基础的二叉搜索树构建出来可能会存在不平衡的现象,比如极端情况下,按照A B C D E F G H
顺序插入树中,结果为,
但实际上我们更想要平衡一点的二叉搜索树,因为平衡的二叉搜索树能有效提高查询效率,比如上面的要查询“H”节点则需要比较8个节点才找到,而平衡的二叉搜索树只需要比较3个节点。
所以AVL树的出现就是为了解决平衡性问题,它的核心内容就是平衡处理机制,即所谓的旋转,一共有四种形式的旋转:右单旋、左单旋、左右双旋和右左双旋。
为什么要旋转
不管是什么方式的旋转,旋转的目的是为了降低树的高度,使其平衡,假如树结构如下图,
将“A”节点添加到树中,变成如下结构,树产生了不平衡,于是检查哪里不平衡,当到“C”节点时发现高度差超过1,
所以需要对“C”节点进行右单旋操作将高度降到2,达到平衡。
插入方式
AVL树一共有四种插入方式,根据插入方式不同需要做不同的旋转操作,现在往下看四种插入方式,设受插入节点影响而失去平衡的节点的父节点为Z,
- LL插入方式,插入的节点在Z节点的左子树的左子树上,如下图,“A”节点插入影响“C”节点的平衡,“C”的父节点为“E”,插入节点“A”在“E”节点的左子树的左子树上。即“B”节点的左右子节点都算LL插入。
- RR插入方式,插入的节点在Z节点的右子树的右子树上,如下图,“I”节点插入影响“G”节点的平衡,“G”的父节点为“E”,插入节点“I”在“E”节点的右子树的右子树上。即“H”节点的左右子节点都算RR插入。
- LR插入方式,插入的节点在Z节点的左子树的右子树上,如下图,“C”节点插入影响“B”节点的平衡,“B”的父节点为“E”,插入节点“C”在“E”节点的左子树的右子树上。即“D”节点的左右子节点都算LR插入。
- RL插入方式,插入的节点在Z节点的右子树的左子树上,如下图,“G”节点插入影响“H”节点的平衡,“H”的父节点为“E”,插入节点“G”在“E”节点的右子树的左子树上。即“F”节点的左右子节点都算RL插入。
右单旋
右单旋用于处理LL插入方式,假设存在一棵树,如下,
现插入“A”节点,假如不进行旋转的话,树结构为下图,所以遍历过程也会检查哪里不平衡,检查到“C”节点和“G”节点的高度差大于1,而且插入节点“A”属于“E”节点左子树的左子树,于是进行右单旋,
“C”节点右单旋即将“C”节点提高,原本它的父节点“E”则变为其右子节点,“C”节点原来的右子节点则变为其父节点“E”的左子节点。右单旋后的结果如下,重新达到了平衡。
左单旋
左单旋用于处理RR插入方式,假设存在一棵树,如下,
现插入“I”节点,假如不进行旋转的话,树结构为下图,所以遍历过程也会检查哪里不平衡,检查到“C”节点和“G”节点的高度差大于1,而且插入节点“I”属于“E”节点的右子树的右子树,于是进行左单旋,
“G”节点左单旋即将“G”节点提高,原本它的父节点“E”则变为其左子节点,“G”节点原来的左子节点则变为其父节点“E”的右子节点。左单旋后的结果如下,重新达到了平衡。
左右双旋
左右双旋用于处理LR插入方式,假设存在一棵树,如下,
现插入“C”节点,假如不进行旋转的话,树结构为下图,遍历过程会检查哪里不平衡,检查到“B”节点和“G”节点的高度差大于1,而且插入节点“C”属于“E”节点的左子树的右子树,于是进行左右双旋,
先以“D”节点为轴进行左单旋,结果为,
再以“D”节点为轴进行右单旋,得到最终结果,
右左双旋
右左双旋用于处理RL插入方式,假设存在一棵树,如下,
现插入“G”节点,假如不进行旋转的话,树结构为下图,遍历过程会检查哪里不平衡,检查到“C”节点和“H”节点的高度差大于1,而且插入节点“G”属于“E”节点的右子树的左子树,于是进行右左双旋,
先以“F”节点为轴进行右单旋,结果为,
再以“F”节点为轴进行左单旋,得到最终结果,
插入
空树时插入节点“E”直接作为根节点,“E”节点高度设为1,
继续插入“B”节点,小于“E”节点则添加到左边,且“E”节点高度加1,
继续插入“G”节点,大于“E”节点则添加到右边,此时“E”节点高度不变,
继续插入“D”节点,最终到“B”节点的右子节点,此时“B”节点高度加1,“E”节点高度也加1,
继续插入“C”节点,最终到“D”节点的左子节点,此时“D”、“B”、“E”节点高度都分别加1,并且先发现节点“D”与它同级节点(不存在即高度为0)高度差大于1,并且属于RL插入方式,使用右左双旋处理,
以“C”节点为轴进行右单旋,结果为,
再以“C”节点为轴进行左单旋,结果如下,可以看到进过右左双旋操作后二叉树已经达到平衡了。
总结,插入时可能会遇到四种不同的插入方式,分别是:LL插入方式、RR插入方式、LR和RL插入方式。根据不同的插入方式对应做旋转操作即能使树达到平衡状态。
查找
AVL树因为属于二叉搜索树,所以查找时与BST树完全一样,比如下面这棵树,查找“D”节点,
从根节点“C”开始,
“D”大于“C”,所以往右继续查找,
“D”小于“E”,所以往左查找,找到。
删除
删除操作主要分两种情况,一种是删除后不会影响平衡,那么直接按照BST树规则删除。另外一种是删除后会影响树的平衡,那么则需要再做旋转处理。
情况一
如树的结构,要删除“B”节点,
直接找到“B”节点,且因为是叶子节点,直接删掉即可。
最终为,
但如果删除的不是“B”节点,而是“C”节点,则不能直接删除“C”节点,
应该先找到“C”节点的前驱,它的前驱为“B”节点,使用“B”替换“C”节点,
最后将原来的“B”节点删除。
情况二
如树的结构,要删除“F”节点,
先找到“F”节点,
然后将“F”节点删除,此时导致了“C”节点和“G”节点的高度差超过1,需要做旋转操作,
而且因为C节点的左子节点高度比右子节点高度大,所以执行右单旋操作,旋转后为,
作者:超人汪小建
链接:https://juejin.im/post/5b6b897df265da0fab404318
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
06-看图理解数据结构与算法系列(AVL树)的更多相关文章
- 09-看图理解数据结构与算法系列(B树)
B树 B树即平衡查找树,一般理解为平衡多路查找树,也称为B-树.B_树.是一种自平衡树状数据结构,能对存储的数据进行O(log n)的时间复杂度进行查找.插入和删除.B树一般较多用在存储系统上,比如数 ...
- 19-看图理解数据结构与算法系列(Radix树)
Radix树 Radix树,即基数树,也称压缩前缀树,是一种提供key-value存储查找的数据结构.与Trie不同的是,它对Trie树进行了空间优化,只有一个子节点的中间节点将被压缩.同样的,Rad ...
- 13-看图理解数据结构与算法系列(Trie树)
Trie树 Trie树,是一种搜索树,也称字典树或单词查找树,此外也称前缀树,因为某节点的后代存在共同的前缀.它的key都为字符串,能做到高效查询和插入,时间复杂度为O(k),k为字符串长度,缺点是如 ...
- 11-看图理解数据结构与算法系列(B树的删除)
删除操作 删除操作比较复杂,主要是因为删除的项可能在叶子节点上也可能在非叶子节点上,而且删除后可能导致不符合B树的规定,这里暂且称之为导致B树不平衡,于是要进行一些合并.左旋.右旋等操作,使之符合B树 ...
- 10-看图理解数据结构与算法系列(B+树)
B+树 B+树是B树的一种变体,也属于平衡多路查找树,大体结构与B树相同,包含根节点.内部节点和叶子节点.多用于数据库和操作系统的文件系统中,由于B+树内部节点不保存数据,所以能在内存中存放更多索引, ...
- 17-看图理解数据结构与算法系列(NoSQL存储-LSM树)
关于LSM树 LSM树,即日志结构合并树(Log-Structured Merge-Tree).其实它并不属于一个具体的数据结构,它更多是一种数据结构的设计思想.大多NoSQL数据库核心思想都是基于L ...
- 看图轻松理解数据结构与算法系列(NoSQL存储-LSM树) - 全文
<看图轻松理解数据结构和算法>,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握.本系列包括各种堆.各种队列.各种列表.各种树.各种图.各种排序等等几十篇的样子. 关于LSM树 ...
- Java数据结构和算法(七)--AVL树
在上篇博客中,学习了二分搜索树:Java数据结构和算法(六)--二叉树,但是二分搜索树本身存在一个问题: 如果现在插入的数据为1,2,3,4,5,6,这样有序的数据,或者是逆序 这种情况下的二分搜索树 ...
- 数据结构与算法:AVL树
AVL树 在计算机科学中,AVL树是最先发明的自平衡二叉查找树.在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树.增加和删除可能需要通过一次或多次树旋转来重新平衡这个树.AV ...
随机推荐
- Windows中句柄和ID的区别
写在前面:这里介绍句柄 对于“句柄”,在下一直停留在一知半解的认识层面,近日在下学习Windows编程,决定趁此机会将句柄彻底搞清楚.查阅了一些网络上的资料,发现网络上的讲解大概可以分为两类:一种是以 ...
- 11.Flask-钩子函数
在Flask中钩子函数是使用特定的装饰器的函数.为什么叫做钩子函数呢,是因为钩子函数可以在正常执行的代码中,插入一段自己想要执行的代码,那么这种函数就叫做钩子函数. before_first_requ ...
- ACM复习专项
资料整理 ACM训练营 邝斌的ACM模板 牛客网哈理工ACM教学视频 视频网盘资料(密码:kntr) 1. 训练阶段 第一阶段:练习经典常用算法 (本周任务) 1. 最短路(Floyd.Dijstra ...
- 187 Repeated DNA Sequences 重复的DNA序列
所有DNA由一系列缩写为A,C,G和 T 的核苷酸组成,例如:“ACGAATTCCG”.在研究DNA时,识别DNA中的重复序列有时非常有用.编写一个函数来查找DNA分子中所有出现超多一次的10个字母长 ...
- 搞定redis面试--Redis的过期策略?手写一个LRU?
1 面试题 Redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现? 2 考点分析 1)我往redis里写的数据怎么没了? 我们生产环境的redis怎么经常会丢掉一些数据?写进去了 ...
- 后缀数组 (Suffix Array) 学习笔记
\(\\\) 定义 介绍一些写法和数组的含义,首先要知道 字典序 . \(len\):字符串长度 \(s\):字符串数组,我们的字符串存储在 \(s[0]...s[len-1]\) 中. \(suff ...
- MySQL学习随笔--视图
视图概念 数据库中的视图指的是一个虚拟表,其内容由查询定义.同真实的表一样,视图也是由行与列构成的.视图的数据来源由SQL语句查询得到,不存储数据 视图创建方法 格式 : create view 视图 ...
- 观锁和乐观锁——《POJOs in Action》
1 事务隔离 事务隔离是数据库提供的功能. SQL Server通过SET TRANSACTION ISOLATION LEVEL语句设置事务隔离级别: SET TRANSACTION ...
- 洛谷 P3388 【模板】割点
题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照 ...
- zabbix3.0.4 部署之八 (zabbix3.0.4 报警前端配置)
(如何让报警信息推送----微信.邮件)(邮件与微信一样就不在重复) 创建一个用户 将用户加入administrator组 添加之前设置的报警媒介脚本 设置报警等级 创建动作 配置报警内容 设置报警条 ...