AVL 树的旋转

news2024/12/30 3:12:06

什么是 AVL 树?

AVL 树是一种自平衡二叉搜索树(Binary Search Tree, BST),以其发明者 G. M. Adelson-Velsky 和 E. M. Landis 的名字命名。它的特点是对于任意一个节点,其左右子树的高度差(平衡因子)不超过 1,这确保了 AVL 树的高度在 O(log n) 的范围内,从而保证了插入、删除和查找操作的时间复杂度都是 O(log n)。

节点结构

// key value 结构
template<class K, class V>
struct AVLTreeNode
{
	AVLTreeNode<K, V>* _parent;
	AVLTreeNode<K, V>* _right;
	AVLTreeNode<K, V>* _left;


	pair<K, V> _kv;
	int _bf;


	AVLTreeNode(const pair<K,V>& kv)
		:_parent(nullptr)
		,_right(nullptr)
		,_left(nullptr)
		,_kv(kv)
		,_bf(0)
	{}

};

平衡因子

对于每个节点,平衡因子定义为其左子树高度减去右子树高度的差值,可能的取值为 -1, 0, 1。当平衡因子的绝对值大于 1 时,表示树不平衡,需要进行旋转操作来恢复平衡。

AVL 树的旋转操作

AVL 树中主要通过旋转来保持平衡。旋转分为四种类型(注意看图,再配合代码思考):

右单旋

新节点插入较高左子树的左侧---左左:右单旋

插入左子树的右侧属于下面的两次旋转的情况,下面左单旋同理

 左子树高度过高导致平衡因子大于 | 1 |

同时这里面我们需要考虑subRL可能不存在的情况,这时候 subRL的父节点不能更新(空指针)

 节点更新需要注意更新顺序,旋转完成后,更新节点的平衡因子

void RotateR(Node * pParent)
{
	Node* subL = parent->_left;
	Node* subLR = subL->_right;

	parent->_left = subLR;

    //防止subLR为nullptr的情况
	if (subLR)
		subLR->_parent = parent;

	subL->_right = parent;
	Node* Parent = parent->_parent;
	parent->_parent = subL;
	subL->_parent = Parent;

	if (Parent == nullptr)
	{
		_root = subL;
	}
	else
	{
		if (Parent->_left == parent)
		{
			Parent->_left = subL;
		}
		else
		{
			Parent->_right = subL;
		}
	}

	subL->_bf = parent->_bf = 0;
}

左单旋

新节点插入较高右子树的右侧---右右:左单旋

  右子树高度过高导致平衡因子大于 | 1 |

同时也要考虑 subRL不存在的情况

void RotateL(Node * parent)
{
	Node* subR = parent->_right;
	Node* subRL = subR->_left;

	parent->_right = subRL;
	if (subRL) subRL->_parent = parent;

	subR->_left = parent;
	Node* Parent = parent->_parent;
	parent->_parent = subR;
	subR->_parent = Parent;

	if (Parent == nullptr)
	{
		_root = subR;
	}
	else
	{
		if (Parent->_left == parent)
		{
			Parent->_left = subR;
		}
		else
		{
			Parent->_right = subR;
		}
	}

	subR->_bf = parent->_bf = 0;
}

左右旋转

新节点插入较高左子树的右侧---左右:先左单旋再右单旋

我们需要记录subRL的平衡因子 是 1 还是 -1 用来判断插入位置是左边还是右边用来更新parent等节点的平衡因子

 

先针对subL左单旋,再针对parent右单旋 

void RotateLR(Node * parent)
{
	Node* subL = parent->_left;
	Node* subLR = subL->_right;
	int bf = subLR->_bf;

	RotateL(subL);
	RotateR(parent);

	if (1 == bf)
		subL->_bf = -1;
	else if (-1 == bf)
		parent->_bf = 1;
}

 右左旋转

同上旋转

void RotateRL(Node * parent)
{
	Node* subR = parent->_reft;
	Node* subRL = subL->_Light;
	int bf = subRL->_bf;

	RotateR(subR);
	RotateL(parent);

	if (1 == bf)
		subR->_bf = 1;
	else if (-1 == bf)
		parent->_bf = -1;
}

ps:注意看图

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

生成树协议(STP:802.1D、RSTP:802.1w、MSTP:802.1s)

在二层网络中&#xff0c;如果没有生成树协议&#xff0c;会带来哪些问题: 1、广播风暴 2、MAC地址表飘移 3、重复数据帧接收 回顾生成树有哪些术语: 1、根桥 为了破除环路&#xff0c;生成树网络首先要选举出一个首脑&#xff0c;头脑&#xff0c;首领。叫做根桥&#xff0c;…

信号有效带宽

根据傅里叶变换可以知道信号带宽是无穷大的&#xff0c;这对实际应用是帮助不大的&#xff0c;所以有了有效带宽的概念&#xff0c;可能大家知道常用的经验公式&#xff1a;O.35/Tr或者0.5/Tr等&#xff0c;那这个公式是怎么来的呢&#xff1f;有效带宽又是什么含义呢&#xff…

C++入门(01)VisualStudio2022社区版HelloWorld

文章目录 1. 下载社区版2. 安装3. 启动4. 创建新项目5. C空项目6. 项目名称和位置7. 创建后&#xff0c;出现“新增功能”&#xff0c;关闭即可8. 解决方案和项目9. 新建源文件10. 编辑第一个C程序11. 运行该程序12. Debug文件夹13. 用好Microsoft Learn 1. 下载社区版 访问&a…

C语言字面量和常量

目录 引言 1. 字面量 1.1 字符字面量 1.2 整型字面量 1.3 浮点字面量 2. 常量 2.1 使用预处理器指令 #define 定义常量 2.1.1 语法格式 2.1.2 使用举例 2.2 使用 const 关键字定义常量 2.3 使用 #define 和 const 定义常量的区别 引言 看了一些博文&#xff0c;有的文…

HarmonyOS(55) error: install releaseType target not same 解决方案

releaseType not same 问题现象解决方法参考资料 问题现象 在DevEco Studio 链接真机运行时发现如下错误&#xff1a; 09/06 08:40:45:905: Install Failed: error: failed to install bundle. code:9568258 error: install releaseType not same. 09/06 08:40:45:966: View …

集成电路学习:什么是SDK软件开发工具包

SDK&#xff1a;软件开发工具包 SDK&#xff0c;即Software Development Kit&#xff08;软件开发工具包&#xff09;&#xff0c;是一套由软件提供商或其他组织提供的开发工具集合。这些工具旨在帮助开发者更快速、更便捷地创建、测试和部署软件应用程序。以下是对SDK的详细解…

全国计算机二级考试C语言篇3——选择题

C语言部分——C语言概述 1.程序模块化的优点 程序模块化的优点在于它可以使程序的开发、维护和复用变得更简单。下面是一些主要的优点&#xff1a; 降低复杂度&#xff1a;模块化可以将复杂的问题分解成更小的、更易管理的部分。 可维护性&#xff1a;模块化使得代码更易于维护…

前缀列表(ip-prefix)配置

一. 实验简介 本来前缀列表是要和访问控制列表放在一起讲的&#xff0c;但是这里单拎出来是为了更详细的讲解两者的区别 1.前缀列表针对IP比访问控制更加灵活。 2.前缀列表在后面被引用时是无法对数据包进行过滤的 实验拓扑 二. 实验目的 R4路由器中只引入子网LoopBack的…

DFS算法专题(一)——二叉树中的深搜【回溯与剪枝的初步注入】

目录 1、DFS算法简介 2、算法实战应用【leetcode】 2.1 计算布尔二叉树的值 2.1.1 算法原理 2.1.2 算法代码 2.2 求根节点到叶节点数字之和 2.2.1 算法原理 ​2.2.2 算法代码 2.3 二叉树剪枝 2.3.1 算法原理 2.3.2 算法代码 2.4 验证二叉搜索树 2.4.1 算法原理 …

紫微斗数算法的实现流程

题外话 我想了又想大凡能够修炼成绝世高手的都是“魔鬼”。只有魔鬼才会纯粹的“敢贪&#xff0c;敢嗔&#xff0c;敢痴”。 你我都困在了敢字。程序猿拿起拿锋利的刀&#xff0c;解构世间的一切吧&#xff01;最近看西游有感而发。 “联系是普遍存在的&#xff0c;规律是客观…

我开源了我的新闻网站项目

&#x1f389; 前言 暑假时写了一个Web项目&#xff0c;感觉做的还是有模有样的&#xff0c;不仅做了前端&#xff0c;还加了后端并连了数据库。最近也是将它开源了&#xff0c;一来是为了熟悉一下Github流程和Git使用命令&#xff0c;二来也是想和大家分享一下自己的成果&…

[阅读笔记]《解读基金—我的投资观与实践》— 季凯帆

&#x1f4e2;博客主页&#xff1a;https://loewen.blog.csdn.net&#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;本文由 丶布布原创&#xff0c;首发于 CSDN&#xff0c;转载注明出处&#x1f649;&#x1f4e2;现…

java环境变量怎么调

java 环境变量配置是设置系统查找和使用 java 工具的路径。通过以下步骤配置&#xff1a;安装 java jdk。设置 path 变量&#xff0c;添加 java 可执行文件目录路径。设置 java_home 变量&#xff0c;指定 jdk 安装目录路径。验证配置&#xff0c;运行 "java -version&quo…

io本质+io效率本质,5种io模型(介绍,异步/同步区别,阻塞/非阻塞区别)

目录 5种io模型 io引入 io的本质 io效率的本质 模型引入 以钓鱼为例 效率最高的方式 异步io和同步io的区别 阻塞式和非阻塞式io的区别 介绍 阻塞式io ​编辑 非阻塞式io ​编辑 信号驱动式io ​编辑 多路转接/复用 ​编辑 异步io 5种io模型 io引入 io的本质…

【鸿蒙HarmonyOS NEXT】页面和自定义组件生命周期

【鸿蒙HarmonyOS NEXT】页面和自定义组件生命周期 一、环境说明二、页面和自定义组件生命周期三、示例代码加以说明四、小结 一、环境说明 DevEco Studio 版本&#xff1a; API版本&#xff1a;以12为主 二、页面和自定义组件生命周期 需要明确几个概念&#xff1a; 页面…

0to1使用Redis实现“登录验证”次数限制

1 引言 系统为了避免密码遭到暴力破解&#xff0c;通常情况下需要在登录时&#xff0c;限制用户验证账号密码的次数&#xff0c;当达到一定的验证次数后&#xff0c;在一段时间内锁定该账号&#xff0c;不再验证。本章将用几行代码实现该功能&#xff0c;完整代码链接在文章最…

Markdown全兼容,MarkText打造专业文档新体验

前言 在科技的洪流中&#xff0c;我们不仅是见证者&#xff0c;更是创造者。它赋予我们力量&#xff0c;将遥不可及的梦想拉近至指尖&#xff0c;让生活的每一刻都充满无限可能。随着数字化内容的爆炸性增长&#xff0c;Markdown作为一种轻量级标记语言&#xff0c;凭借其简洁…

tekton构建标准ci(clone repo, test, build push img)

场景介绍 我们在上一篇文章中构建了一个最简单的ci&#xff0c;接下来我们对我们的github的项目构建一个较标准的ci。 Tekton简介&#xff0c;安装和构建最简单ci/cd-CSDN博客文章浏览阅读239次&#xff0c;点赞2次&#xff0c;收藏2次。本文介绍了tekton是什么&#xff0c;如…

vsftpd配置用户和密码让其他客户端连接

一、第一个主机:vsftpd下载及配置 前置准备: #卸载防火墙 yum -y remove firewalld #为了不让防火墙有影响&#xff0c;iptables配置也清空 iptables -F vim /etc/selinux/conf SELINUXdisabled #主要是把它改为disabled或者permissive SELINUXTYPEtargeted #重启linux让seli…

[Web安全 网络安全]-安全法规 网络基础 信息收集

文章目录&#xff1a; 一&#xff1a;网络安全法规 二&#xff1a;计算机网络 1.计算机网络的组成 2.网络分层模型&#xff08;OSI七层 TCP/IP四层&#xff09; 3.通信协议 IP协议 UDP协议/TCP协议 TCP协议 UDP协议 区别 HTTP协议/HTTPS协议 HTTP协议 HTTPS协议…