平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
当二叉树不平衡时,可以通过左单旋,右单旋,左右双旋,右左双旋的方式将它调整平衡;
平衡因子=左右子树高度之差[-1,1]
如图:
左单旋:
右单旋:
左右双旋:
右左双旋:
#include<iostream>
using namespace std;
template<class K,class V>
struct AVLTreeNode
{
AVLTreeNode(const K& key, const V& value)
: _key(key)
, _value(value)
, pLeft(NULL)
, pRight(NULL)
, pParent(NULL)
, _bf(0)
{}
AVLTreeNode < K,V>* pLeft;
AVLTreeNode < K, V>* pRight;
AVLTreeNode < K, V>* pParent;
K _key;
V _value;
int _bf;//平衡因子
};
template<class K, class V>
class AVLTree
{
public:
AVLTree()
:_pRoot(NULL)
{}
bool Insert(const K& key, const V& value)
{
if (_pRoot == NULL)
{
_pRoot = new AVLTreeNode<K,V>(key,value);
return true;
}
AVLTreeNode<K, V>* pCur = _pRoot;
AVLTreeNode<K, V>* parent = NULL;
while (pCur)
{
//若节点存在,则不必插入
//若节点的值小于key,则key插入节点的右子树
//若节点的值大于key,则key插入节点的左子树
if (key == pCur->_key)
return false;
if (key > pCur->_key)
{
parent = pCur;
pCur = pCur->pRight;
}
else if(key < pCur->_key)
{
parent = pCur;
pCur = pCur->pLeft;
}
}
//插入节点,并给出孩子节点与双亲结点的关系
pCur = new AVLTreeNode<K,V>(key, value);
if (key>parent->_key)
{
parent->pRight = pCur;
pCur->pParent = parent;
}
else
{
parent->pLeft = pCur;
pCur->pParent = parent;
}
//更新平衡因子(右子树高度-左子树高度[-1,1])
while (parent)
{
//若当前节点是双亲结点的左孩子,平衡因子-1
//若当前节点是双亲结点的右孩子,平衡因子+1
if (parent->pLeft == pCur)
parent->_bf--;
if (parent->pRight == pCur)
parent->_bf++;
if (parent->_bf == 0)
return true;
else
{
if (parent->_bf == 1 || parent->_bf == -1)
{
pCur = parent;
parent = parent->pParent;
}
else
{
//同号单旋(正左负右),异号双旋
if (parent->_bf == 2)
{
if (pCur->_bf == -1)//右左双旋
_RotateRL(parent);
else if (pCur->_bf == 1)//左单旋
_RotateL(parent);
}
else if (parent->_bf == -2)
{
if (pCur->_bf == 1)//左右双旋
_RotateLR(parent);
else if (pCur->_bf == -1)//右单旋
_RotateR(parent);
}
break;
}
}
}
return true;
}
private:
//右单旋
void _RotateR(AVLTreeNode<K, V>*& parent)
{
AVLTreeNode<K, V>* subL = parent->pLeft;
AVLTreeNode<K, V>* subLR = subL->pRight;
parent->pLeft = subLR;
if (subLR != NULL)
subLR->pParent = parent;
subL->pRight = parent;
subL->pParent = parent->pParent;
AVLTreeNode<K, V>* rPrarent = parent->pParent;
parent->pParent = subL;
if (rPrarent == NULL)
{
_pRoot = subL;
}
else
{
if (rPrarent->pLeft == parent)
rPrarent->pLeft = subLR;
else
rPrarent->pRight = subLR;
}
parent->_bf = subL->_bf = 0;
}
//左单旋
void _RotateL(AVLTreeNode<K, V>*& parent)
{
AVLTreeNode<K, V>* subR = parent->pRight;
AVLTreeNode<K, V>* subRL = subR->pLeft;
parent->pRight = subRL;
if (subRL != NULL)
subRL->pParent =parent;
subR->pLeft = parent;
subR->pParent = parent->pParent;
AVLTreeNode<K, V>* rPrarent = parent->pParent;
if (rPrarent == NULL)
_pRoot = subR;
else
{
if (rPrarent->pLeft == parent)
rPrarent->pLeft = subR;
else
rPrarent->pRight = subR;
}
parent->_bf = subR->_bf = 0;
}
//右左双旋
void _RotateRL(AVLTreeNode<K, V>*& parent)
{
AVLTreeNode<K, V>* subR = parent->pRight;
AVLTreeNode<K, V>* subRL = subR->pLeft;
int bf = subRL->_bf;//0.1,-1
//右单旋
_RotateR(parent->pRight);
//左单旋
_RotateL(parent);
if (bf == -1)
{
parent->_bf = 0;
subR->_bf = 1;
subRL->_bf = 0;
}
else if (bf == 1)
{
parent->_bf = -1;
subR->_bf = 0;
subRL->_bf = 0;
}
}
//左右双旋
void _RotateLR(AVLTreeNode<K, V>*& parent)
{
AVLTreeNode<K, V>* subL = parent->pLeft;
AVLTreeNode<K, V>* subLR = subL->pRight;
int bf = subLR->_bf;//0,1,-1
//左单旋
_RotateL(parent->pLeft);
//右单旋
_RotateR(parent);
if (bf == -1)
{
parent->_bf = 1;
subLR->_bf = 0;
subL->_bf = 0;
}
else if (bf==1)
{
parent->_bf = 0;
subLR->_bf = 0;
subL->_bf = -1;
}
}
private:
AVLTreeNode<K, V>* _pRoot;
};
测试函数:
void AVLTreeTest()
{
AVLTree<int, int> at;
int arr[] = { 50, 40, 60, 30, 45, 42 };
//int arr[] = { 50, 40, 30, 45, 20, 60 };
for (int idx = 0; idx < sizeof(arr) / sizeof(arr[0]); idx++)
{
at.Insert(arr[idx],arr[idx]);
}
}