AVL树(平衡二叉树)

AVL树是一种高度平衡的二叉搜索树,通过控制节点的平衡因子确保搜索效率。插入操作可能导致旋转,以维持平衡。适合静态数据且查询频繁,但结构修改操作性能较低。
摘要由CSDN通过智能技术生成

前言

        二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当 于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年 发明了一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之 差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度,这就是AVL树

一、AVL树的概念

        一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树:

1.它的左右子树都是AVL树。

2.左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1)。

如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持O(log2n),搜索时间复杂度O(log2n)。

二、控制二叉搜索树的子树高度差

1.AVL树节点的定义

代码如下(示例):

	template<class K,class V>
	struct AVLTNode
	{
		typedef AVLTNode<K,V> Node;

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

		Node* _parent;
		Node* _left;
		Node* _right;
		pair<K, V> _kv;
		int _bf;       //平衡因子
	};

2.平衡因子

        结点的左子树的深度减去右子树的深度,即结点的平衡因子 = 右子树的高度 - 左子树的高度 。通过节点的平衡因子来控制高度差。

        新插入节点父亲及祖先平衡因子(bf)变化规律:

1.新增节点在左子树,父亲bf--,反之在右子树则父亲bf++。

2.更新后如果bf==0,父亲的子树高度不变,则不需要继续向上更新平衡因子。

3.更新后如果bf==-1 or 1,父亲所在的子树高度变化,继续向上更新。

4.更新后如果bf==2 or -2,则父亲所在子树违反规则,需要旋转

3.搜索二叉树的旋转

        如果在一棵原本是平衡的AVL树中插入一个新节点,可能造成不平衡,此时必须调整树的结构,使之平衡化。根据节点插入位置的不同,AVL树的旋转分为四种:

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

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

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

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

        将双旋变成单旋后再旋转,即:先对30进行左单旋,然后再对90进行右单旋,旋转完成后再考虑平衡因 子的更新。

以上四种情况可以做出以下总结:

三、AVL树的性能

        AVL树是一棵绝对平衡的二叉搜索树,其要求每个节点的左右子树高度差的绝对值都不超过1,这样可以保证 查询时高效的时间复杂度,即O(log2(n)) 。但是如果要对AVL树做一些结构修改的操作,性能非常低下,比如: 插入时要维护其绝对平衡,旋转的次数比较多,更差的是在删除时,有可能一直要让旋转持续到根的位置。 因此:如果需要一种查询高效且有序的数据结构,而且数据的个数为静态的(即不会改变),可以考虑AVL树, 但一个结构经常修改,就不太适合,这时候就适合用红黑树


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值