AVL树就是在二叉搜索树的基础上添加了平衡因子,为了平衡因子符合不超过(-1 / 1 / 1)的条件,所以有时候在插入的时候要对树进行调整。它的插入就是在二叉搜索树插入的基础上进行对树进行调整,使之符合AVL树的性质
ALV树节点的定义:
template<class T>
class AVLTreeNode
{
typedef AVLTreeNode Node;
public:
AVLTreeNode(const T& data)
:_pLeft(nullptr)
,_pRight(nullptr)
,_pParent(nullptr)
,_data(data)
,_bf(0)
{}
Node<T>* _pLeft;
Node<T>* _pRight;
Node<T>* _pParent;
T _data;
int _bf // 节点的平衡因子
};
AVL树的插入
template<class T>
class AVLTree
{
typedef AVLTreeNode Node;
public:
AVLTree()
:_root(nullptr)
{}
bool insert(const T& data)
{
if(_root == nullptr)
{
_root = new Node(data);
return true;
}
// 按照二叉搜索树节点的性质插入
// 1. 找插入位置
Node* cur = _root;
Node* pparent = nullptr;
while(cur)
{
pparent = cur;
if(data < cur->_data)
cur = cur->_pLeft;
else if(data> cur->_data)
cur = cur->_pParent;
else
return false;
}
// 2.插入新节点
cur = new Node(data);
if(data > pparent->_data)
pparent->_pRight = cur;
else
pparent->_pLeft = cur;
cur->_pParent = pparent;
// AVL树在新的节点插入之后会破坏树的平衡性
// 检测平衡性
// 更新双亲的平衡因子
while()
{
if(data > pparent->_data) // 右
pparent->_bf++;
else // 左
pparent->_bf--;
//
if(0 == pparent->_bf )
return true;
else if(1 == pparent->_bf || -1 == pparent->_bf)
{
// 树中的左右子树高度增加了,需要往上更新
cur = pparent;
pparent = cur->_pParent;
}
else
{
// 平衡因子 2 或 -2
// 旋转处理
// 单旋转 、 双旋转
}
}
return true;
}
Node* _root
};