文章目录
一、AVL树的概念
二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉树将退化成单支树,查找元素相当于在顺序表中搜索元素,效率低下。于是引出了AVL树的概念,当向二叉搜索树中插入新节点后,如果能保证每个节点的左右子树高度之差的绝对值不超过1(需要对树中节点进行调整),即可降低树的高度,从而减少平均搜索长度。(左右子树高度之差(简称平衡因子)的绝对值不超过(-1/0/1)
二、AVL树中节点的定义
struct AVLTreeNode
{
pair<K,V> _kv;
//使用三叉链
AVLTreeNode<K,V>*_left;
AVLTreeNode<K,V>*_right;
AVLTreeNode<K,V>*_parent;
//右子树-左子树的高度差
int _bf;//平衡调节因子
AVLTreeNode(const pair<K,V>&kv)
:_kv(kv)
,_left(nullptr)
,_right(nullptr)
,_parent(nullptr)
{}
};
三、AVL树的插入
1.调节节点的平衡因子
2.AVL树的旋转
1.左单旋
//左单旋
void RotateL(Node*parent)
{
Node*subR=parent->_right;
Node*subRL=subR->_left;
parent->_right=subRL;
if(subRL)
subRL->_parent=parent;
Node*ppNode=parent->_parent;
subR->_left=parent;
parent->_parent=subR;
if(parent==_root)
{
_root=subR;
_root->_parent=nullptr;
}
else
{
if(parent==ppNode->_left)
{
ppNode->_left=subR;
}
else
{
ppNode->_right=subR;
}
subR->_parent=ppNode;
}
parent->_bf=suR->_bf=0;
}
//右单旋
void RotateR(Node*parent)
{
Node*subL=parent->_left;
Node*subLR=subL->_right;
if(subLR)
{
subLR->_parent=subL;
}
Node*ppNode=parent->_parent;
subL->_right=parent;
parent->_parent=subL;
if(parent==_root)
{
_root=subL;
_root->_parent=nullptr;
}
else
{
if(parent==ppNode->_left)
{
ppNode->_left=subL;
}
else
{
ppNode->_right=subL;
}
subL->_parent=ppNode;
}
subL->_bf=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)
{
parent->_bf = 0;
subL->_bf = 0;
subLR->_bf = 0;
}
else if (bf == 1)
{
parent->_bf = 0;
subL->_bf = -1;
subLR->_bf = 0;
}
else if (bf == -1)
{
parent->_bf = 0;
subL->_bf = 0;
subLR->_bf = 1;
}
else
assert(false);
}
//先右单旋再左单旋
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 = 0;
parent->_bf = -1;
subR->_bf = 0;
}
else if (bf == 1)
{
subRL->_bf = 0;
parent->_bf = -1;
subR->_bf = 0;
}
else
{
subRL->_bf = 0;
parent->_bf = 0;
subR->_bf = 1;
}
else
{
assert(false);
}
}
四、判断一下是否是AVL树
bool _isBalanceTree(Node* root)
{
if (root == nullptr)
return true;
int leftHeight = _Height(root->_left);
int rightHeight = _Height(root->_right);
int diff = rightHeight->leftHeight;
if (abs(diff) >= 2)
{
return false;
}
else if (diff != root->_bf)
{
return false;
}
return _isBalanceTree(root->_left) && _isBalanceTree(root->right);
}