AVL的旋转

AVL的旋转

  • AVL树是一棵高度平衡树,树中任何节点的两个子树的高度最大差别为1。

  • 我们可以在节点中加入一个变量,该变量用来判断当前节点是否平衡,当该节点的左子树发生变化时,我们可以将平衡因子进行减1,当该节点的右子树发生变化时,我们可以将该节点的平衡因子进行加1。所以当这棵子树平衡时它的平衡因子为0,当平衡因子为2或者-2时,此时就需要进行旋转。

特点

  • 本身首先是一颗二叉搜索树。
  • 自带平衡条件:每个节点的左右子树高度差不差过1。

节点

template <class K, class V>
struct AVLTreeNode
{
	AVLTreeNode* _left;
	AVLTreeNode* _right;
	AVLTreeNode* _parent;
	pair<K, V>_kv;
	int _bf;//平衡因子

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

右单旋

当插入的节点位于较高左子树的左侧时

image-20220519151307251

	//右单旋
	void RotateR(Node* cur)
	{
		Node* left = cur->_left;
		Node* parent = cur->_parent;

		cur->_left = left->_right;
		if (cur->_left)
			cur->_left->_parent = cur;
		left->_right = cur;
		cur->_parent = left;
		left->_parent = parent;
		if (_root == cur) {
			_root = left;
		}
		else {
			if (parent->_kv.first > left->_kv.first) {
				parent->_left = left;
			}
			else
				parent->_right = left;
		}
		left->_bf = cur->_bf = 0;
	}

左单旋

当插入位置位于较高右子树的右侧时,进行左单旋

image-20220519151407651

	void RotateL(Node* cur)
	{
		Node* right = cur->_right;
		Node* parent = cur->_parent;

		cur->_right = right->_left;
		right->_left = cur;
		cur->_parent = right;
		if (cur->_right)
			cur->_right->_parent = cur;
		right->_parent = parent;
		if (_root == cur) {
			_root = right;
		}
		else {
			if (parent->_kv.first > right->_kv.first)
				parent->_left = right;
			else
				parent->_right = right;
		}
		cur->_bf = right->_bf = 0;
	}

左右双旋

image-20220519151534077

	//左旋加右旋
	void RotateLR(Node* cur)
	{
		Node* left = cur->_left;
		Node* leftR = left->_right;
		int bf = leftR->_bf;
		RotateL(left);
		RotateR(cur);
		if (bf == -1) {
			left->_bf = 0;
			cur->_bf = 1;
			leftR = 0;
		}
		else if (bf == 1) {
			left->_bf = -1;
			cur->_bf = 0;
			leftR->_bf = 0;
		}
		else if (bf == 0) {
			left->_bf = 0;
			cur->_bf = 0;
			leftR->_bf = 0;
		}
		else {
			//出错了
			assert(false);
		}
	}

右左双旋

image-20220519151610324

	void RotateRL(Node* cur)
	{
		Node* right = cur->_right;
		Node* rightL = right->_left;
		int bf = rightL->_bf;
		RotateR(right);
		RotateL(cur);
		if (bf == -1) {
			right->_bf = 1;
			cur->_bf = 0;
			rightL->_bf = 0;
		}
		else if (bf == 1) {
			right->_bf = 0;
			cur->_bf = -1;
			rightL->_bf = 0;
		}
		else if (bf == 0) {
			right->_bf = 0;
			cur->_bf = 0;
			rightL->_bf = 0;
		}
		else {
			//出错了
			assert(false);
		}
	}

完整代码

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值