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后面插入,如果在这插入一次旋转不能解决问题。

代码:

三.右左双旋

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

四.左右双旋

总代码:

相关推荐
二本咕咕-机械转码1 小时前
FreeRTOS深入解析(八)IPC机制之FromISR详解
数据结构·单片机·链表
1-1=03 小时前
C# 数据结构和特殊类型
数据结构·c#·.net·.netcore
希和20273 小时前
C语言程序设计题|有序数组插入数字冒泡排序
c语言·数据结构·算法
布莱克60514 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
D e re k ZH17 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法
zh_xuan1 天前
LeeCode 496. 下一个更大元素I
数据结构·算法·栈·单调栈
白杨尚青1 天前
C++进阶篇(五):红黑树——四条规则、三种插入情况与旋转变色
开发语言·数据结构·c++·stl·红黑树·平衡二叉树
likexuec2 天前
数据结构(2)
数据结构
D e re k ZH2 天前
C++ 标准库算法全景指南
数据结构·c++·算法
冻柠檬飞冰走茶2 天前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划