AVL树又称为高度平衡的二叉搜索树,是1962年有俄罗斯的数学家G.M.Adel’son-Vel’skii和E.M.Landis提出来的。它能保持二叉树的高度
平衡,尽量降低二叉树的高度,减少树的平均搜索长度。
AVL树的性质
1. 左子树和右子树的高度之差的绝对值不超过1
2. 树中的每个左子树和右子树都是AVL树
3. 每个节点都有一个平衡因子(balance factor–bf),任一节点的平衡因子是-1,0,1。(每个节点的平衡因子等于右子树的高度减去左子
树的高度 )
AVL树的效率
一棵AVL树有N个节点,其高度可以保持在logN,插入/删除/查找的时间复杂度也是logN。
template <class K,class V>
struct AVLTreeNode //节点
{
K _key;
V _value;
int _bf;
AVLTreeNode<K, V>* _pLeft;
AVLTreeNode<K, V>* _pRight;
AVLTreeNode<K, V>* _parent;
AVLTreeNode(const K key, const V value)
:_key(key)
, _value(value)
, _bf(0) //平衡因子
, _pLeft(NULL)
, _pRight(NULL)
, _parent(NULL)
{}
};
template<class K,class V>
class AVLTree
{
typedef AVLTreeNode<K,V> Node;
public:
AVLTree()
:_pRoot(NULL)
{}
bool Insert(const K key, const V value) //插入
{
if (_pRoot == NULL)
{
_pRoot = new Node(key, value);
return true;
}
Node* pCur = _pRoot;
Node* Pparent = _pRoot;
while (pCur) //寻找插入位置
{
if (key < pCur->_key)
{
Pparent = pCur;
pCur = pCur->_pLeft;
}
else if (key>pCur->_key)
{
Pparent = pCur;
pCur = pCur->_pRight;
}
else
return false;
}
pCur = new Node(key, value);
if (key < Pparent->_key) //插入节点
{
Pparent->_pLeft = pCur;
pCur->_parent = Pparent;
}
else
{
Pparent->_pRight = pCur;
pCur->_parent = Pparent;
}
while (Pparent) //更新平衡因子
{
if (pCur == Pparent->_pLeft)
Pparent->_bf--;
else
Pparent->_bf++;
if (Pparent->_bf == 0) //判断平衡因子
break;
else if (Pparent->_bf == -1 || Pparent->_bf == 1)
{
pCur = Pparent;
Pparent = pCur->_parent;
}
else //平衡因子为2或-2 需要进行旋转
{
if (Pparent->_bf == -2)
{
if (pCur->_bf == -1)
{
RotateR(Pparent);
break;
}
else
{
RotateLR(Pparent);
break;
}
}
if (Pparent->_bf == 2)
{
if (pCur->_bf == 1)
{
RotateL(Pparent);
break;
}
else
{
RotateRL(Pparent);
break;
}
}
}
}
}
void RotateR(Node* pParent) //右旋
{
assert(pParent);
Node* subL = pParent->_pLeft;
Node* subLR = subL->_pRight; //可能为空
pParent->_pLeft = subLR; //断开pparent的左
if (subLR)
{
subLR->_parent = pParent;
}
subL->_pRight = pParent;
Node* pNode = pParent->_parent;
pParent->_parent = subL;
if (pNode == NULL) //pParent为根节点
{
_pRoot = subL;
subL->_parent = NULL;
}
else
{
if (pNode->_pLeft = pParent)
pNode->_pLeft = subL;
else //pParent为Node的右孩子
pNode->_pRight = subL;
subL->_parent = pNode;
}
subL->_bf = pParent->_bf = 0; //旋转后平衡
}
void RotateL(Node* pParent)
{
assert(pParent);
Node*subR = pParent->_pRight;
Node*subRL = subR->_pLeft;
pParent->_pRight = subRL;
if (subRL)
{
subRL->_parent = pParent;
}
subR->_pLeft = pParent;
Node* pNode = pParent->_parent;
pParent->_parent = subR;
if (pNode == NULL)
{
_pRoot = subR;
subR->_parent = NULL;
}
else
{
if (pParent == pNode->_pLeft)
pNode->_pLeft = subR;
else
pNode->_pRight = subR;
subR->_parent = pNode;
}
subR->_bf = pParent->_bf = 0;
}
void RotateLR(Node* pParent) //左右旋
{
assert(pParent);
Node*subL = pParent->_pLeft;
Node*subLR = subL->_pRight;
int bf = subLR->_bf;
RotateL(pParent->_pLeft);
RotateR(pParent);
if (bf == 1)
{
pParent->_bf = 0;
subL->_bf = -1;
}
else if (bf == -1)
{
subL->_bf = 0;
pParent->_parent->_bf = 1;
}
else
subL->_bf = pParent->_bf = 0;
subLR->_bf = 0;
}
void RotateRL(Node* pParent)
{
assert(pParent);
Node*subR = pParent->_pRight;
Node*subRL = subR->_pLeft;
int bf = subRL->_bf;
RotateR(pParent->_pRight);
RotateL(pParent);
if (bf == 1)
{
pParent->_bf = -1;
subR->_bf = 0;
}
else if (bf == -1)
{
pParent->_bf = 0;
subR->_bf = 1;
}
else
subR->_bf = pParent->_bf = 0;
subRL->_bf = 0;
}
int Height(Node* pRoot)
{
if (pRoot == NULL)
return 0;
int leftH = Height(pRoot->_pLeft);
int rightH = Height(pRoot->_pRight);
return leftH > rightH ? leftH + 1 : rightH + 1;
}
bool IsBalance()
{
return _IsBalance(_pRoot);
}
private:
bool _IsBalance(Node* p)
{
if (p == NULL)
return false;
int leftH = Height(p->_pLeft);
int rightH = Height(p->_pRight);
if (rightH - leftH != p->_bf)
cout << "平衡因子异常" << p->_key << endl;
return abs(rightH - leftH) < 2 //绝对值
&& _IsBalance(p->_pLeft)
&& _IsBalance(p->_pRight);
}
Node* _pRoot;
};