AVLTree----平衡二叉搜索树

1.定义:AVL树又称为高度平衡的二叉搜索树,它能保持二叉树的高度平衡,尽量降低二叉树的高度,减少树的平均搜索长度。

2.AVL树的性质

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

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

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

3.效率

一棵AVL树有N个节点,其高度可以保持在log以2为底N的对数,插入/删除/查找的时间复杂度也是log以2为底N的对数。

4.更新平衡因子的情况

(1). 当父节点平衡因子为0时,停止,此时树的高度没变。

(2). 当父节点平衡因子为1/-1时,向上调整其祖父节点的平衡因子。

(3). 当平衡因子为2/-2时,此时树已经不平衡了,需要旋转此树使树保持平衡。

5.旋转的情况


6.代码

节点:

template<class	K,class V>
struct AVLTreeNode
{
	
	V _value;
	K _key;
	int _bf;
	AVLTreeNode<K,V>* _left;
	AVLTreeNode<K,V>* _right;
	AVLTreeNode<K,V>* _parent;
	AVLTreeNode()
		:_key(0)
		,_value(0)
		,_left(NULL)
		,_right(NULL)
		,_parent(NULL)
		,_bf(0)
	{}
	AVLTreeNode(const K& key,const V& value)
		:_key(key)
		,_value(value)
		,_left(NULL)
		,_right(NULL)
		,_parent(NULL)
		,_bf(0)
	{}
};
插入:
bool Insert(const K& key,const V& value)
	{
		if(_root==NULL)
		{
			_root=new Node(key,value);
			return true;
		}
		Node* cur=_root;
		Node* parent=cur;
		while(cur)
		{
			if(cur->_key >key)
			{
				parent=cur;
				cur=cur->_left;
		    }
			else if(cur->_key <key)
			{
				parent=cur;
				cur=cur->_right ;
			}
			else 
				return false; //存在
		}
		cur=new Node(key,value);
		if(parent->_key>key)  //左
		{
			parent->_left =cur;
			cur->_parent =parent;
			parent->_bf --;
		}
		else    //右
		{
		    parent->_right =cur;
			cur->_parent =parent;
			parent->_bf ++;
		} 
		if(parent==0)   //树的高度没变
		{
			return true;
		}
		else 
		{
			cur=parent;
			parent=parent->_parent ;
			//调整平衡因子
			while(parent)
			{
				if(parent->_left ==cur)
				{
					parent->_bf --;
				}
				else if(parent->_right ==cur)
				{
					parent->_bf ++;
				}
		   		//旋转
				if(parent->_bf ==2&&cur->_bf ==1)
				{
					_RotateL(parent);
					break;
				}
				if(parent->_bf ==-2&&cur->_bf ==-1)
				{
					_RotateR(parent);
					break;
				}
				if(parent->_bf ==-2&&cur->_bf ==1)
				{
					_RotateLR(parent);
					break;
				}
				if(parent->_bf ==2&&cur->_bf ==-1)
				{
					_RotateRL(parent);
					break;
				}
				cur=parent;
				parent=parent->_parent ;
			}
		}
	}

旋转:

void _RotateL(Node* parent)
	{
		Node* subR=parent->_right ;
		Node* subRL=subR->_left ;
		parent->_right=subRL;
		if(subRL)
			subRL->_parent =parent;
		Node* PPNode=parent->_parent ;
		if(PPNode==NULL)
		{
			_root=subR;
			_root->_parent =NULL;
		}
		else
		{
			if(PPNode->_left ==parent)
				PPNode->_left =subR;
			else
				PPNode->_right =subR;
			subR->_parent =PPNode;
		}
		subR->_left =parent;
		parent->_parent =subR;
		parent->_bf =0;
		subR->_bf =0;
	}
	void _RotateR(Node* parent)
	{
		Node* subL=parent->_left ;
		Node* subLR=subL->_right ;
		parent->_left =subLR;
		if(subLR)
			subLR->_parent =parent;
		Node* PPNode=parent->_parent ;
		if(PPNode==NULL)
		{
			_root=subL;
			_root->_parent =NULL;
		}
		else
		{
			if(PPNode->_left ==parent)
				PPNode->_left =subL;
			else
				PPNode->_right =subL;
			subL->_parent =PPNode;
		}
		subL->_right =parent;
		parent->_parent =subL;
		subL->_bf =0;
		parent->_bf =0;
	}
	void _RotateLR(Node* parent)
	{
		Node* subL=parent->_left ;
		Node* subLR=subL->_right ;
		int bf=subLR->_bf ;   //重点

		_RotateL(parent->_left );
		_RotateR(parent);
		
		if(bf ==0)
			subLR->_bf =parent->_bf =subL->_bf =0;
		else if(bf ==1)
		{
			parent->_bf =0;
			subL->_bf =-1;
		}
		else if(bf==-1)
		{
			parent->_bf =1;
			subL->_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==0)
			subRL->_bf =parent->_bf =subR->_bf =0;
		else if(bf==1)
		{
			parent->_bf  =-1;
			subR->_bf =0;
		}
		else if(bf==-1)
		{
			parent->_bf =0;
			subR->_bf =1;
		}
	}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值