C++之AVL树

普通二叉搜索树在有序数据输入下会退化为链表,查询效率下降。所以发明了AVL树;

AVL树 是最先发明的⾃平衡⼆叉查找树 ,AVL是⼀颗空树,或者具备下列性质的⼆叉搜索树:它的
左右⼦树都是AVL树,且左右⼦树的⾼度差的绝对值不超过1
。AVL树是⼀颗⾼度平衡搜索⼆叉树,并且通过控制⾼度差去控制平衡。

实现这棵树有多种方式,这边介绍一种通过平衡因子 来实现。AVL树通过平衡因子与旋转操作维持左右子树高度平衡,保证增删查时间复杂度稳定为O(log n)。每个结点都有⼀个平衡因⼦,任何
结点的平衡因⼦等于右⼦树的⾼度减去左⼦树的⾼度
,也就是说任何结点的平衡因⼦等于0/1/-1,

AVL树并不是必须要平衡因⼦,但是有了平衡因⼦可以更⽅便我们去进⾏观察和控制树是否平衡,

每个节点上面为平衡因子;

现在我们把14的左子树连接一个13,那么在10这边的平衡因子就发生异常,通常平衡因子是右子树高度减左子树高度,在10这个节点右边最远走到13,有两层,在10的左边没有子树就是0,那么这个节点的平衡因子就是2,超过了1就需要旋转,来重新使得这棵树变得平衡;

我们先讲里面的算法细节,总代码框架在最后给出;

一.右单旋

下面的子树长条为抽象表示,在这个长条里面这个子树可能有2层3层甚至更多,这个情况就是成千上万种了,不可能一一列举出来,但是基本上它这个就是一个节点的平衡因子有异常就说明这里需要旋转,然后一直往上旋转,直到所有平衡因子全部正常,所以我们只拿出来其中一部分需要旋转的来研究;

1.正常树

2.插入一个节点到subL的左子树后面,平衡因子异常

3.右旋转,把subLR连接在parent的左边,这边为什么连接在这?在没旋转前它就是在parent的左边,subL的右边,这课抽象的subLR中所有值就在10和5之间,所以在右旋后把subLR连接在parent的左边,这样就把这一部分里面的平衡因子恢复正常了。

当然你也可以插入subLR后面,旋转中操作都是一样的,只是在最后有个节点的因子不是0;但是也会在正常范围里面;

代码:

二.左单旋

这个跟上面的一样我就直接给代码了,这里不能在subRL后面插入,如果在这插入一次旋转不能解决问题。

代码:

三.右左双旋

右左双旋和左右双旋比较难,结合图形理解

四.左右双旋

总代码:

相关推荐
wabs6662 小时前
关于二叉树【429.N叉树的层序遍历的思考】
数据结构·c++·算法·leetcode·二叉树
C++ 老炮儿的技术栈3 小时前
MFC CPtrArray的用法
开发语言·数据结构·c++·算法·mfc·c
不会就选b3 小时前
算法日常・每日刷题--<贪心>6
数据结构·算法·leetcode
青山木3 小时前
Hot 100 --- 跳跃游戏 II
java·数据结构·算法·leetcode·贪心算法
神明不懂浪漫4 小时前
【第四章】索引——B+树、回表,加快数据库的查找能力的利器
开发语言·数据结构·数据库·经验分享·笔记·b树
LuminousCPP5 小时前
数据结构 - 排序(二):快速排序从错误初版到优化版|双指针划分 + 三数取中 + 小区间插入优化
c语言·数据结构·笔记·算法·排序算法
hansang_IR5 小时前
【题解】P9753 [CSP-S 2023] 消消乐
数据结构·c++·算法
shehuiyuelaiyuehao5 小时前
算法40,模拟运算,替换所有的问号
数据结构·算法·leetcode
YSL0701246 小时前
OpenCode保姆级安装教程
数据结构