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;
}
}