AVL树(高度平衡的二叉搜索树)平衡因子的调节和旋转

1.什么叫AVL树?

               
   AVL树又称为高度平衡的二叉搜索树,它能保持二叉树的高度平衡,尽量降低二叉树的高度,减少树的平均搜索长度(尽量使这棵树保持为完全二叉树,这样就能提高搜索效率)。


2.AVL树的性质

      
(1)左子树和右子树的高度之差的绝对值不超过1

          (2) 树中的每个左子树和右子树都是AVL树  

          (3) 每个节点都有一个平衡因子(balance factor–bf),任一节点的平衡因子是-1,0,1。(每个节点的平衡因子等于右子树的高度减去左子  树的高度)

3.AVL树节点的定义

template <typename K,typename V>
struct AVLTreeNode
{
	K _key;
	V _value;
	int _bf; //平衡因子,只能取值为-1,1,0
	AVLTreeNode<K, V>* _left;
	AVLTreeNode<K, V>* _right;
	AVLTreeNode<K, V>* _parent;
	AVLTreeNode(const K& key, const V& value)
		:_key(key)
		, _value(value)
		, _bf(0)
		, _left(NULL)
		, _right(NULL)
		, _parent(NULL)
	{}
};





4.AVL树左单旋的情况


《AVL树(高度平衡的二叉搜索树)平衡因子的调节和旋转》



对应代码实现:

void _RotateL(Node* &parent)
	{
		//1.将要修改的结点标记起来
		Node* SubR = parent->_right;
		Node* SubRL = SubR->_left;
		Node* pparent = parent->_parent;
		//2.重新链上SubR结点
		SubR->_left = parent;
		SubR->_parent = pparent;
		SubR->_bf = 0;
		//4.重新链上parent结点
		parent->_right = SubRL;
		parent->_parent = SubR;
		parent->_bf = 0;
		//5.改变pparent的指向结点
		if (pparent == NULL)
			_root = SubR;
		else if (pparent->_left == parent)
			pparent->_left = SubR;
		else
			pparent->_right = SubR;
		//4.重新链上SubRL结点
		if (SubRL != NULL)
			SubRL->_parent = parent;
		
	}

5.AVL树右单旋的情况
《AVL树(高度平衡的二叉搜索树)平衡因子的调节和旋转》



对应的代码实现:

	void _RotateR(Node* &parent)
	{
		//1.将要修改的结点标记起来
		Node* SubL = parent->_left;
		Node* SubLR = SubL->_right;
		Node* pparent = parent->_parent;
		//2.重新链上SubL结点
		SubL->_right = parent;
		SubL->_parent = parent->_parent;
		SubL->_bf = 0;
		//3.重新链上parent结点
		parent->_left = SubLR;
		parent->_parent = SubL;
		parent->_bf = 0;
		//4.改变pparent的指向结点
		if (pparent == NULL)
			_root = SubL;
		else if (pparent->_left == parent)
			pparent->_left = SubL;
		else
			pparent->_right = SubL;
		//5.重新链上SubRL结点
		if (SubLR != NULL)
			SubLR->_parent = parent;
	}

6.AVL树平衡因子的调节


     (1)插入的数据只能影响祖先结点的平衡因子;
    
     (2)当某个平衡因子从0变成1或者-1,需要继续调整祖先结点的平衡因子,直到根节点;
     
     (3)当某个平衡因子从-1或者1变成0,则不需要调整祖先的平衡因子了,因为平衡因子在插入数据之后变成0,证明整棵树的高度没有发生变化;
《AVL树(高度平衡的二叉搜索树)平衡因子的调节和旋转》



     (4)当平衡因子在插入数据之后变成-2或者2,需要通过旋转来降低它的高度,使它继续保持AVL树的性质


7.AVL树进行左右双旋的情况(注意平衡因子的调节


《AVL树(高度平衡的二叉搜索树)平衡因子的调节和旋转》





代码实现:

	void _RotateLR(Node* &parent)
	{
		//双旋的时候在某些情况下会导致bf发生异常
		Node* SubL = parent->_left;
		Node* SubLR = SubL->_right;
		int bf = SubLR->_bf;
		_RotateL(parent->_left);
		_RotateR(parent);
		if (bf == -1)
		{
			parent->_bf = 1;
			SubL->_bf = 0;
		}
		else if (bf == 1)
		{
			parent->_bf = 0;
			SubL->_bf = -1;
		}
		else
		{
			SubL->_bf = parent->_bf = 0;
		}
		SubLR->_bf = 0;
	}

8.同样的方法可以得到右左双旋时平衡因子的变化
《AVL树(高度平衡的二叉搜索树)平衡因子的调节和旋转》



                  (1)SubRL->_bf==0   parent->_bf=SubR->_bf=0;


  (2)SubRL->_bf==-1  parent->_bf=0  SubR->_bf=1;


  (3)SubRL->_bf==1   parent->_bf=-1 SubR->_bf=0;


代码实现:

	void _RotateRL(Node* &parent)
	{
		Node* SubR = parent->_right;
		Node* SubRL = SubR->_left;
		int bf = SubRL->_bf;
		_RotateR(parent->_right);
		_RotateL(parent);
		if (bf == 1)
		{
			parent->_bf = -1;
			SubR->_bf = 0;
		}
		else if (bf == -1)
		{
			parent->_bf = 0;
			SubR->_bf = 1;
		}
		else
		{
			SubR->_bf = parent->_bf = 0;
		}
		SubRL->_bf = 0;
	}






    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/skyroben/article/details/72824146
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞