平衡搜索二叉树—AVL树

news2024/11/20 10:23:31

一、定义:

        为了避免搜索二叉树的高度增长过快,降低二叉树的性能,规定在插入和删除二叉树的结点的时候,任何结点左右子树的高度差绝对值不超过1,这样的二叉树被称为平衡二叉树(balanced Binary Tree),简称平衡树。在搜索二叉树BST的基础上增加以上性质,就称为AVL树。

二、AVL树的构造

      1. AVL树的结点是一个三叉链结构:相比BST多了一个指向parent的结点。

template<class K,class V>
struct AVLTreeNode {
	
	pair<K,V> _kv;//结点值
	
	AVLTreeNode* _parent;//指针,三叉链
	AVLTreeNode* _left;
	AVLTreeNode* _right;
	
	int _bf;//平衡因子
	

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

  2.AVL树的插入:

  1. 首先,从根结点开始,与待插入结点比较大小,直到直到插入位置——叶子结点的空孩子指针,然后建立新结点,并与父节点链接。
  2. 然后修改插入结点的父节点的平衡因子,左节点插入,平衡因子-1,反之,加1。
  3. 父节点平衡因子修改后,分三种情况处理:

①父节点平衡因子为0,不用处理return。

②父节点平衡因子为±1,向上传递,回到第二步,此时cur=parent,parent=grantparent,根据cur和parent的位置关系,修改平衡因子。

③父节点平衡因子为±2,根据插入结点cur、parent以及grandparent的位置,分4种情况,进行4种旋转结束。

 3.AVL树的四种旋转

右单旋:条件为
条件为:if (parent->_bf == 2 && cur->_bf == 1)

 所有情况下的结构图如下:h>=0

	void rotateR(Node* parent)
	{
		Node* cur = parent->_left;
		Node* cur_right = cur->_right;

		parent->_left = cur_right;		//旋转第一步parent和cur_right的链接;
		if (cur->_right != nullptr)//X
			cur_right->_parent = parent;


		cur->_right = parent;		//再处理cur和parent的链接
		Node* parent_parent = parent->_parent;//保存结点,用于处理,cur->parent;
		parent->_parent = cur;

		if (parent == _root)		//处理cur和parent_parent的链接
		{
			_root = cur;
			cur->_parent = nullptr;//X
		}
		else {
			cur->_parent = parent_parent;
			if (parent_parent->_left == parent)
			{
				parent_parent->_left = cur;
			}
			else {
				parent_parent->_right = cur;
			}
		}
		parent->_bf = 0;//旋转后平衡因子为0
		cur->_bf = 0;
	}
左单旋:
条件为:if(parent->_bf==2&&cur->_bf==1)

  所有情况下的结构图如下:h>=0

void rotateL(Node* parent) {
	Node* cur = parent->_right;
	Node* cur_left = cur->_left;

	parent->_right = cur_left;
	if(cur_left!=nullptr)
	cur_left->_parent = parent;
	

	cur->_left = parent;
	Node* ppNode = parent->_parent;
	parent->_parent = cur;

	if (parent == _root)
	{
		_root = cur;
		cur->_parent = nullptr;
	}
	else
	{
		if (ppNode->_left == parent)
		{
			ppNode->_left = cur;
		}
		else
		{
			ppNode->_right = cur;
		}
		cur->_parent = ppNode;
	}
	parent->_bf = 0;
	cur->_bf = 0;
}
先左后右双旋:
条件是 if(parent->_bf==-2&&cur->_bf==-1)

结构图如下: 注意H==0时,H-1=0

void rotateLR(Node* parent) {
	Node* cur = parent->_left;
	Node* cur_right = cur->_right;
	int bf = cur_right->_bf;//根据此节点的平衡因子决定,上层三个参加旋转的结点的平衡因子

	rotateL(parent->_left);//对平衡因子==±1的结点,即上层堆栈的cur,作为单左旋的parent,旋转后转为,单右旋的情况,再单右旋。
	rotateR(parent);

	if (bf == 1) {
		parent->_bf = 0;
		cur->_bf = -1;
		cur_right = 0;
	}
	else if (bf == -1) {
		parent->_bf = -1;
		cur->_bf =0;
		cur_right->_bf = 0;
	}
	else if (bf == 0) {
		parent->_bf = 0;
		cur->_bf = 0;
		cur_right->_bf = 0;
	}
	else {
		assert(false);
	}
}
先右后左双旋:
条件是:if(parent->_bf==2&&parent->_bf==-1)

结构图如下: 注意H==0时,H-1=0

	void rotateRL(Node* parent) {
		Node* cur = parent->_right;
		Node* cur_left = cur->_left;
		int bf = cur_left->_bf;

		rotateR(parent->_right);
		rotateL(parent);
		if (bf == -1) {
			parent->_bf = 0;
			cur->_bf = 1;
			cur_left->_bf = 0;
		}
		else if (bf == 1) {
			parent->_bf = -1;
			cur->_bf = 0;
			cur_left->_bf = 0;
		}
		else if (bf == 0) {//当cur_left的子节点为空时,bf=0,
			parent->_bf = 0;
			cur->_bf = 0;
			cur_left->_bf = 0;
		}
		else {
			assert(false);
		}
	}

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

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

相关文章

为PDF创建目录(侧边栏目录)

通过可以新建书签的pdf阅读器。 知云翻译&#xff1a;可以新建书签和子书签。 Adobe Acrobat&#xff1a;只能新建书签&#xff0c;不能建立子书签。

DA14531在三星手机手写笔的应用让我打开眼镜

手写笔的功能 这是一款内置蓝牙功能的魔性笔&#xff0c;它是遥控器、是照相、切换摄像头、是暂停或者打开播放列表。乃至更多操作-通过不同的手势隔空操作&#xff0c;或者按下触控按键便可轻松搞定。 手写笔硬件设计 内部结构 采用2.3V可循环充电电池&#xff0c;放入手…

软件测试零基础新手入门必看

软件测试&#xff1a;使用技术手段验证软件是否满足使用需求 目的&#xff1a;减少缺陷&#xff0c;保证质量 一、测试主流技能&#xff1a; 1.功能测试 测试主要验证程序的功能是否满足需求 2.自动化测试 使用工具或代码代替手工&#xff0c;对项目进行测试 3.接口测试 …

【原理图PCB专题】Allegro模块化移动器件报...has the LOCKED property怎么解锁?

在模块化原理图时,PCB也需要做一个模块.mdd文件。这时需要先画好图纸然后再制作模块化文件。 修改文件时会发现模块化器件报错,无法编辑模块内部器件和走线,器件和走线都被LOCKED,如下所示报错内容: Symbol "U1" Selected Cannot edit Symbol "U1". M…

(Linux学习七)进程介绍

一、进程 进程生命周期&#xff1a;由系统程序。form出来的子程序&#xff0c;具备一定的父的资源&#xff08;权利&#xff0c;内存空间&#xff0c;PID&#xff09;直到运行完毕&#xff0c;退出系统 查看进程 ps aux 查看所有进程参数&#xff1a;aux ps a 显示现行…

剑指offer 二维数组中的查找 C++

目录 前言 一、题目 二、解题思路 1.直接查找 2.二分法 三、输出结果 前言 最近在牛客网刷题&#xff0c;刷到二维数组的查找&#xff0c;在这里记录一下做题过程 一、题目 描述 在一个二维数组中&#xff08;每个一维数组的长度相同&#xff09;&#xff0c;每一行都按照…

00. Nginx总结-错误汇总

/www/wangmingqu/index.html" is forbidden (13: Permission denied) 错误图片 错误日志 2024/01/09 22:26:27 [error] 1737#1737: *1 "/www/wangmingqu/index.html" is forbidden (13: Permission denied), client: 192.169.1.101, server: www.wangmingqu.c…

前端知识点、技巧、webpack、性能优化(持续更新~)

1、 请求太多 页面加载慢 &#xff08;webpack性能优化&#xff09; 可以把 图片转换成 base64 放在src里面 减少服务器请求 但是图片会稍微大一点点 以上的方法不需要一个一个自己转化 可以在webpack 进行 性能优化 &#xff08;官网有详细描述&#xff09;

数据结构与算法:堆排序和TOP-K问题

朋友们大家好&#xff0c;本节内容来到堆的应用&#xff1a;堆排序和topk问题 堆排序 1.堆排序的实现1.1排序 2.TOP-K问题3.向上调整建堆与向下调整建堆3.1对比两种方法的时间复杂度 我们在c语言中已经见到过几种排序&#xff0c;冒泡排序&#xff0c;快速排序&#xff08;qsor…

光伏发电预测

XGB、LGB在datacamp(学习网站) data fountain与国家电投系列赛,光伏发电预测 题目:给一组特征,预测瞬时发电量,训练集9000个点,测试集8000个点,特征包含光伏板的属性和外部环境等。 数据字段:ID、光伏电池板背侧温度、光伏电站现场温度、计算得到的平均转换效率、数…

Javaweb之SpringBootWeb案例之自动配置案例的自定义starter分析的详细解析

3.2.4.1 自定义starter分析 前面我们解析了SpringBoot中自动配置的原理&#xff0c;下面我们就通过一个自定义starter案例来加深大家对于自动配置原理的理解。首先介绍一下自定义starter的业务场景&#xff0c;再来分析一下具体的操作步骤。 所谓starter指的就是SpringBoot当…

数据删除

目录 数据删除 删除员工编号为 7369 的员工信息 删除若干个数据 删除公司中工资最高的员工 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 数据删除 删除数据就是指删除不再需要的数据 delete from 表名称 [where 删…

HTML+CSS+BootStrap景区官网

一、技术栈 支持pc、pad、手机访问&#xff0c;页面自适应&#xff01;&#xff01; html5cssbootstrapjs 二、项目截图 接受项目定制&#xff0c;站内联系博主&#xff01;&#xff01;&#xff01;

算法学习03:前缀和与差分(互逆)

算法学习03&#xff1a;前缀和与差分&#xff08;互逆&#xff09; 文章目录 算法学习03&#xff1a;前缀和与差分&#xff08;互逆&#xff09;前言一、前缀和1.一维2.二维 二、差分1.一维在这里插入图片描述2.二维在这里插入图片描述 ![在这里插入图片描述](https://img-blog…

CSS全局样式的设置,web开发交流

面试题 HTML 1&#xff0c;html5有哪些新特性&#xff1f; 2&#xff0c;html5移除了那些元素&#xff1f; 3&#xff0c;如何处理HTML5新标签的浏览器兼容问题 戳这里领取完整开源项目&#xff1a;【一线大厂前端面试题解析核心总结学习笔记Web真实项目实战最新讲解视频】…

Vue+腾讯地图-实现关键词输入提示功能

不废话&#xff0c;上代码~~~ 效果图&#xff1a; 1、先去腾讯地图后台创建自己的应用获取到应用的 Key 腾讯地图后台地址&#xff1a;腾讯位置服务 - 立足生态&#xff0c;连接未来 创建应用的 Key 如下&#xff1a; 2、在项目中添加腾讯地图API的js插件&#xff0c;如…

Android开发者该学习哪些东西提高竞争力,Github上最值得学习的10个Android开源项目

什么是 HTTPS? HTTPS (基于安全套接字层的超文本传输协议 或者是 HTTP over SSL) 是一个 Netscape 开发的 Web 协议。 你也可以说&#xff1a;HTTPS HTTP SSL HTTPS 在 HTTP 应用层的基础上使用安全套接字层作为子层。 为什么需要 HTTPS &#xff1f; 超文本传输协议 (…

2024第十二届济南国际生物发酵产品与技术装备展览会胜利开幕

聚焦生物新产品新技术 引领生物产业发展新趋势 3月5日&#xff0c;2024第十二届济南国际生物发酵产品与技术装备展览会在济南市山东国际会展中心隆重举行。这次展览会&#xff0c;由中国生物发酵产业协会主办&#xff0c;山东省生物发酵产业协会协办&#xff0c;上海信世展览…

通过人工智能增强的对话建立有意义的联系

人工智能如何重塑我们的交流&#xff1f;2024年最新对话AI趋势 在技术和人类互动比以往任何时候都更加复杂地交织在一起的时代&#xff0c;人工智能增强的对话已成为建立有意义的联系的关键要素。 这种转变不仅关乎效率&#xff0c;还关乎效率。 这是为了丰富沟通的结构。 在这…

关于我使用numpy.random.choice()遇到坑这件事

做仿真时经常使用到随机数&#xff0c;下面是一个场景&#xff1a;使用np.random.choice([0,1],p[0.5,0.5],size1)去进行随机的二选一&#xff0c;假设需要随机选择1000次&#xff0c;为了保证结果的稳健性&#xff0c;对前述过程重复50次&#xff0c;为了保证可复现性&#xf…