AVL树概念

二叉搜索树的缺点

  当二叉树数据是一条直线时,它就变成一个链表,效率极大降低,所以引入了平衡二叉树

AVL树(平衡二叉搜索树)概念

任意结点其左右子树高度相差不大于1

要做到平衡一个二叉树并不容易,在每个结点中放入一个平衡因子,平衡因子来判断是否为平衡二叉树,平衡因子只能等于0 1 -1

如果不是,那么就需要旋转,这个是平衡二叉树最重要的步骤

插入节点

1、插入在左边,parent平衡因子-1  ,  插入在右边,parent平衡因子+1

2、当parent为1或-1,需要向上更新祖先节点平衡因子

3、当parent为2或-2,需要进行旋转,更新parent的平衡因子

1.左旋

2.右旋

3.双旋

什么时候需要双旋?

parent平衡因子为2,并且parent,cur,插入节点,三个不在同一直线时,需要双旋

左旋再右旋

这里分为两种情况

1、在curleft左边插入

2、在curlefr右边插入

因为在curleft右边插入后,该节点比curleft要大,左旋之后不能放在curleft的左边

右旋再左旋

与左旋再右旋类似,都会出现两种情况

旋转代码

	void RotateL(Node* parent)
	{
		Node* cur = parent->_right;
		Node* curleft = cur->_left;

		cur->_left = parent;

		if (curleft)
			curleft = parent->_right;

		parent->_parent = cur;
		parent->_right = curleft;

		Node* ppnode = parent->_parent;
		//判断parent是否是_root
		if (parent == _root)
		{
			_root = cur;
			cur->_parent = nullptr;
		}
		else
		{
			if (ppnode->_left==parent)//(ppnode->_kv.first > cur->_kv.first)
			{
				ppnode->_left = cur;
			}
			else
			{
				ppnode->_right = cur;
			}

			cur->_parent = ppnode;
		}

		parent->_bf = cur->_bf = 0;
	}

	void RotateR(Node* parent)
	{
		Node* cur = parent->_left;
		Node* curright = cur->_right;

		cur->_left = parent;

		if (curright)
			curright = parent->_right;

		parent->_parent = cur;
		parent->_right = curright;

		Node* ppnode = parent->_parent;
		//判断parent是否是_root
		if (parent == _root)
		{
			_root = cur;
			cur->_parent = nullptr;
		}
		else
		{
			if (ppnode->_left == parent)//(ppnode->_kv.first > cur->_kv.first)
			{
				ppnode->_left = cur;
			}
			else
			{
				ppnode->_right = cur;
			}

			cur->_parent = ppnode;
		}

		parent->_bf = cur->_bf = 0;
	}

	//双旋
	//p
	//  c
	//cl
	//1、cl平衡因子为0
	//2、cl平衡因子为1
	//3、cl平衡因子为-1
	void RotateRL(Node* parent)
	{
		Node* cur = parent->_right;
		Node* curleft = cur->_left;
		int bf = curleft->_bf;

		RotateR(cur);
		RotateL(curleft);

		if (bf==0)
		{
			cur->_bf = 0;
			parent->_bf = 0;
			curleft->_bf = 0;
		}
		else if (bf == 1)
		{
			cur->_bf = 0;
			parent->_bf = -1;
			curleft->_bf = 0;
		}
		else if(bf == -1)
		{
			cur->_bf = 1;
			parent->_bf = 0;
			curleft->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}


	//  p
	//c
	// cr
	void RotateLR(Node* parent)
	{
		Node* cur = parent->_left;
		Node* curright = cur->_right;
		int bf = curright->_bf;

		RotateL(cur);
		RotateR(curright);

		if (bf == 0)
		{
			cur->_bf = 0;
			parent->_bf = 0;
			curright->_bf = 0;
		}
		else if (bf == 1)
		{
			cur->_bf = 0;
			parent->_bf = -1;
			curright->_bf = 0;
		}
		else if (bf == -1)
		{
			cur->_bf = -1;
			parent->_bf = 0;
			curright->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值