数据结构【AVL树】

AVL树

1.AVL树

1.AVL的概念

AVL树可以是一个空树。

它的左右子树都是AVL树,且左右子树的高度差的绝对值不超过1。AVL树是一颗高度平衡搜索二叉树,通过控制高度差去控制平衡。

AVL树整体结点数量和分布和完全二叉树类似,高度可以控制在 logN ,那么增删查改的效率也可以控制在O(logN ) ,相比二叉搜索树有了本质的提升。

2.平衡因子

结点的平衡因子 =右子树的高度减去左子树的高度,也就是说任何结点的平衡因子等于0/1/-1,AVL树并不是必须要平衡因子,但是有了平衡因子可以更方便我们去进行观察和控制树是否平衡,就像⼀个风向标一样。

为什么AVL树是高度平衡搜索二叉树,要求高度差不超过1,而不是高度差是0呢?

因为例如二和四个结点无法达到0.

2.AVl树的实现

2.1AVL树的结构

cpp 复制代码
template<class K, class V>
struct AVLTreeNode
{
	// 需要parent指针,后续更新平衡因⼦可以看到
	pair<K, V> _kv;
	AVLTreeNode<K, V>* _left;
	AVLTreeNode<K, V>* _right;
	AVLTreeNode<K, V>* _parent;
	int _bf; // balance factor
	AVLTreeNode(const pair<K, V>& kv)
		:_kv(kv)
		, _left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _bf(0)
	{
	}
};
template<class K, class V>
class AVLTree
{
	typedef AVLTreeNode<K, V> Node;
public:
	//...
private:
	Node * _root = nullptr;
};

2.2AVL树的插入

cpp 复制代码
bool Insert(const pair<K, V>& kv)
{
	if (_root == nullptr)
	{
		_root = new Node(kv);
		return true;
	}
	Node* parent = nullptr;
	Node* cur = _root;
	while (cur)
	{
		if (cur->_kv.first < kv.first)
		{
			parent = cur;
			cur = cur->_right;
		}
		else if (cur->_kv.first > kv.first)
		{
			parent = cur;
			cur = cur->_left;
		}
		else
		{
			return false;
		}
	}
		cur = new Node(kv);
	if (parent->_kv.first < kv.first)
	{
		parent->_right = cur;
	}
	else
	{
		parent->_left = cur;
	}
	cur->_parent = parent;
	// 更新平衡因⼦
	while (parent)
	{
		// 更新平衡因⼦
		if (cur == parent->_left)
			parent->_bf--;
		else
			parent->_bf++;
		if (parent->_bf == 0)
		{
			// 更新结束
			break;
		}
		else if (parent->_bf == 1 || parent->_bf == -1)
		{
			// 继续往上更新
			cur = parent;
			parent = parent->_parent;
		}
		else if (parent->_bf == 2 || parent->_bf == -2)
		{
			// 不平衡了,旋转处理
			break;
		}
		else
		{
			assert(false);
		}
	}
	return true;
}

2.3 旋转

2.3.1 旋转的原则

保持搜索树的规则

让旋转的树从不满足变平衡,其次降低旋转树的高度

旋转总共分为四种,左单旋/右单旋/左右双旋/右左双旋。

相关推荐
逆境不可逃9 分钟前
LeetCode 热题 100 之 35. 搜索插入位置 74. 搜索二维矩阵 34. 在排序数组中查找元素的第一个和最后一个位置
数据结构·算法·leetcode
浅念-16 分钟前
C ++ 智能指针
c语言·开发语言·数据结构·c++·经验分享·笔记·算法
不染尘.18 分钟前
最小生成树算法
开发语言·数据结构·c++·算法·图论
程序员老乔24 分钟前
Java 新纪元 — JDK 25 + Spring Boot 4 全栈实战(二):Valhalla落地,值类型如何让电商DTO内存占用暴跌
java·spring boot·c#
Klong.k31 分钟前
判断是不是素数题目
数据结构·算法
祝大家百事可乐43 分钟前
嵌入式——02 数据结构
c++·c#·硬件工程
耶叶44 分钟前
Android 新权限申请模型(Activity Result API)
android
阿拉斯攀登1 小时前
【RK3576 安卓 JNI/NDK 系列 04】JNI 核心语法(下):字符串、数组与对象操作
android·驱动开发·rk3568·瑞芯微·rk安卓驱动·jni字符串操作
2501_915909061 小时前
不用越狱就看不到 iOS App 内部文件?使用 Keymob 查看和导出应用数据目录
android·ios·小程序·https·uni-app·iphone·webview
llxxyy卢1 小时前
web部分中等题目
android·前端