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

代码:

三.右左双旋

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

四.左右双旋

总代码:

相关推荐
quaer4 小时前
弗洛伊德算法--判圈法寻找环的入口O(n) O(1)
数据结构·算法
xys_6788 小时前
深挖数据结构:树和二叉树(上)
数据结构·算法
BeiGuTing_code8 小时前
Java动态数组(一)
java·数据结构·windows
Code_Solitude12 小时前
传智杯备赛代码整理(前4题)
数据结构·算法
Jasmine_llq12 小时前
《P8816 [CSP-J 2022] 上升点列》
数据结构·算法·贪心·排序·二维动态规划 dp·类背包状态转移
辛苦才能13 小时前
C++ 哈希表深度解析:删除为什么必须打标记,负载因子为什么卡 0.7
开发语言·数据结构·c++·算法
JasmineX-113 小时前
数据结构(笔记)——顺序栈
c语言·数据结构·笔记
凉茶钱15 小时前
list:哨兵节点,const_iterator 和 const iterator的区别与迭代器失效
数据结构·c++·list
敲代码的苦1316 小时前
头歌数据结构-排序的实现及其应用
数据结构
有同事要进步17 小时前
Leecode第68题:x的平方根
java·数据结构·算法