平衡二叉树的旋转
Posted 宏睿技术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了平衡二叉树的旋转相关的知识,希望对你有一定的参考价值。
一、平衡二叉树的定义
为避免树的高度增长过快,降低二叉树的排序性能,规定在插入和删除二叉树结点时,保证任意结点的左右子树高度差的绝对值不大于1。这样的二叉树被称为平衡二叉树(Balanced Binary Tree)。
二、平衡因子
平衡因子:结点的平衡因子 = 结点的左子树深度 — 结点的右子树深度。若平衡因子的取值为-1、0或1时,该节点是平衡的,否则是不平衡的。
最低不平衡结点:用A表示最低不平衡结点,则A的祖先结点可能有不平衡的,但其所有后代结点都是平衡的。
简单理解为:一个结点的左右子树高度差不超过一,超过一就不平衡,需要进行旋转。
二、LL平衡旋转(右单旋转)
B→根节点,B的右子树成为A的左子树
实现代码:
void rRotate(Node *Parent)//LL
{
Node *subL = Parent->_pLeft;
Node *subLR = subL->_pRight;
Parent->_pLeft = subLR;
if (subLR)//左单支
subLR->_parent = Parent;
subL->_pRight = Parent;
Node *pParent = Parent->_parent;
Parent->_parent = subL;
subL->_parent = pParent;
if (NULL == pParent)//Parent是根节点
_pRoot = subL;
else if (Parent == pParent->_pLeft)
pParent->_pLeft = subL;
else
pParent->_pRight = subL;
//修改平衡因子
subL->_bf = 0;
Parent->_bf = 0;
}
三、RR旋转(左单旋转)B左上为根,B的左子树成为A的右子树
实现代码:
void lRotate(Node *Parent)//RR
{
Node *subR = Parent->_pRight;
Node *subRL = subR->_pLeft;
Parent->_pRight = subRL;
if (subRL)
subRL->_parent = Parent;
subR->_pLeft = Parent;
subR->_parent = Parent->_parent;
Parent->_parent = subR;
Node *pParent = subR->_parent;
if (NULL == pParent)
_pRoot = subR;
else if (Parent == pParent->_pLeft)
pParent->_pLeft = subR;
else
pParent->_pRight = subR;
Parent->_bf = 0;
subR->_bf = 0;
}
四、LR平衡双旋转(先左后右双旋转)由基础旋转组合而来
实现代码:
void lrRotate(Node *Parent)//LR
{
Node *subL = Parent->_pLeft;
Node *subLR = subL->_pRight;
int bf = subLR->_bf;
lRotate(Parent->_pLeft);
rRotate(Parent);
if (1 == bf)
subL->_bf = -1;
else if (-1 == bf)
Parent->_bf = 1;
subLR->_bf = 0;
}
五、RL平衡旋转(先右后左双旋转)组合旋转,可以分为两步进行旋转
实现代码:
void rlRotate(Node *Parent)
{
Node *subR = Parent->_pRight;
Node *subRL = subR->_pLeft;
int bf = subRL->_bf;
rRotate(Parent->_pRight);
lRotate(Parent);
if (1 == bf)
Parent->_bf = -1;
else if (-1 == bf)
subR->_bf = 1;
subRL->_bf = 0;
}
AVL树插入代码:
bool Insert(const K& key, const V& value)
{
Node *pNew = new Node(key,value);
Node *pCur = _pRoot;
Node *parent = NULL;
if (NULL == _pRoot)
{
_pRoot = pNew;
return true;
}
while (pCur)//寻找插入位置
{
if (key < pCur->_key)
{
parent = pCur;
pCur = pCur->_pLeft;
}
else if (key > pCur->_key)
{
parent = pCur;
pCur = pCur->_pRight;
}
else
return false;
}
if (key < parent->_key)//插入元素
parent->_pLeft = pNew;
else
parent->_pRight = pNew;
pNew->_parent = parent;
//修改平衡因子
while (parent)
{
if (pNew == parent->_pLeft)
parent->_bf--;
else
parent->_bf++;
if (0 == parent->_bf)
return true;
else if (1 == parent->_bf || -1 == parent->_bf)
{
pNew = parent;
parent = parent->_parent;
}
else//2需要进行旋转
{
if (-2 == parent->_bf && -1 == pNew->_bf)//LL
rRotate(parent);
else if (2 == parent->_bf && 1 == pNew->_bf)//RR
lRotate(parent);
else if (-2 == parent->_bf && 1 == pNew->_bf)//LR
lrRotate(parent);
else if (2 == parent->_bf && -1 == pNew->_bf)//RL
rlRotate(parent);
return true;
}
}
return true;
}
本文参考算法网平衡二叉树旋转详解,和王道论坛。
以上是关于平衡二叉树的旋转的主要内容,如果未能解决你的问题,请参考以下文章