数据结构【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 旋转的原则

保持搜索树的规则

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

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

相关推荐
05候补工程师15 分钟前
【408考研复习】数据结构核心笔记:字符串模式匹配与内部排序算法全解析
数据结构·经验分享·笔记·考研·算法·排序算法
问心无愧051320 分钟前
ctf show web入门107
android·前端·笔记·android studio
AI科技星37 分钟前
第三卷:质数王朝志 第四章:RSA护国玄阵,质数锁天地,一数镇万法
android·人工智能·架构·概率论·学习方法
欧阳x天40 分钟前
八大排序算法(C语言实现)
数据结构·算法·排序算法
AFinalStone1 小时前
Android12 U盘插拔链路源码全解析(八)实战调试与案例分析
android·frameworks
我命由我123451 小时前
Android 开发问题:View 的 getWidth、getHeight 方法返回的值都为 0
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
Chris _data2 小时前
c#学习WPF笔记(一)
学习·c#·wpf
SoftLipaRZC3 小时前
单链表的应用:经典OJ题与通讯录项目实战
数据结构
SoftLipaRZC3 小时前
单链表专题:从概念到实现
数据结构
JohnnyDeng9411 小时前
【Android】Hilt 依赖注入:原理与最佳实践
android·kotlin·mvvm·hilt