文章目录
- 一.右单旋
- 二. 左单旋
- 三. 右左双旋
- 四. 左右双旋
一.右单旋
新节点插入较高左子树的左侧—左左:右单旋
由于在较高左子树的左侧插入一个节点后,左边插入导致30的平衡因子更新为-1,而60平衡因子更新为-2,此时不平衡,引发旋转,右旋解决问题:看下图
:
将60进行一次右单旋后,30和60的平衡因子都更新为了0,此时AVL树重新平衡,更新结束。
代码实现:
void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
if(subLR)
subLR->_parent = parent;
subL->_right = parent;
Node* ppnode = parent->_parent;
parent->_parent = subL;
if (parent == _root)
{
_root = subL;
subL->_parent = nullptr;
}
else
{
if (parent == ppnode->_left)
{
ppnode->_left = subL;
}
else
{
ppnode->_right = subL;
}
subL->_parent = ppnode;
}
parent->_bf = 0;
subL->_bf = 0;
}
二. 左单旋
新节点插入较高右子树的右侧—右右:左单旋
由于在较高右子树的右侧插入一个节点后,右边插入导致30的平衡因子更新为1,而60平衡因子更新为2,此时不平衡,引发旋转,左旋解决问题:看下图
:
将60进行一次左单旋后,30和60的平衡因子都更新为了0,此时AVL树重新平衡,更新结束。
代码实现:
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if (subRL)
subRL->_parent = parent;
subR->_left = parent;
Node* ppnode = parent->_parent;
parent->_parent = subR;
if (_root == parent)
{
_root = subR;
subR->_parent = nullptr;
}
else
{
if (parent == ppnode->_left)
{
ppnode->_left = subR;
}
else
{
ppnode->_right = subR;
}
subR->_parent = ppnode;
}
parent->_bf = 0;
subR->_bf = 0;
}
三. 右左双旋
新节点插入较高右子树的左侧—右左:先右单旋再左单旋
此时进行右左双旋分为三种情况:
情况一:h==0
插入新结点后,60自己就是新增节点
此时先将60进行右旋
再将30进行左旋
情况二:h>0,在c插入(这里以h2为例)
同上理旋转:
先90进行右旋
最后30进行左旋
情况三:h>0,在b插入(这里以h2为例)
先将90进行右旋
再将30进行左旋
右左双旋代码实现:
void RotateRL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = parent->_left;
int bf = subRL->_bf;
RotateLR(subR);
RotateL(parent);
subRL->_bf = 0;
if (bf == -1)
{
subR->_bf = 1;
parent->_bf = 0;
}
else if (bf == 1)
{
subR->_bf = 0;
parent->_bf = -1;
}
else if (bf == 0)
{
subR->_bf = 0;
parent->_bf = 0;
}
else
{
assert(false);
}
}
四. 左右双旋
新节点插入较高左子树的右侧—左右:先左单旋再右单旋
此时进行左右双旋分为三种情况:
情况一:h==0
插入新结点后,60自己就是新增节点
30进行左旋
90进行右旋
情况二:h>0,在c插入(这里以h2为例)
30进行左旋
90进行右旋
情况三:h>0,在b插入(这里以h2为例)
30进行左旋
90进行右旋
左右双旋代码实现:
void RotateLR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
int bf = subLR->_bf;
RotateL(subL);
RotateR(parent);
subLR->_bf = 0;
if (bf == 0)
{
subL->_bf = 0;
parent->_bf = 0;
}
else if (bf == 1)
{
subL->_bf = -1;
parent->_bf = 0;
}
else if (bf == -1)
{
subL->_bf = 0;
parent->_bf = 1;
}
else
{
assert(false);
}
}
**总结:1.对于单旋,旋转之后就平衡了,结束 2.对于双旋,旋转之后也平衡了,但此时要更新平衡因子,怎么更新取决于更新前代码中subL的平衡因子,
分三种情况,具体看代码实现。