通常,我们在平衡二叉树进行插入和删除的时候常常会破坏平衡二叉树,所以我们必须通过一种方法来再次平衡二叉树使之成为平衡二叉树,这种办法就是旋转。
旋转可以分为四种,分别为:
1.左单旋转
2.右单旋转
3.先左后右双向旋转
4.先右后左双向旋转
接下来我们去分析这四种旋转并且依次用代码实现
1.左单旋转
旋转过程:
在原有的平衡树中插入20这个节点,导致不平衡,通过旋转调整使树平衡,这个过程就称为左单旋转。
代码实现:
void RotateL(AVLNode<Type> *&ptr)
{
AVLNode<Type> *subL = ptr;
ptr = subL->rightChild;
subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
subL->bf = ptr->bf = 0;
}
2.右单旋转
旋转过程:
在原有的平衡树中插入8这个节点,导致不平衡,通过旋转调整使树平衡,这个过程就称为右单旋转。
代码实现:
void RotateL(AVLNode<Type> *&ptr)
{
AVLNode<Type> *subL = ptr;
ptr = subL->rightChild;
subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
subL->bf = ptr->bf = 0;
}
3.先左后右双向旋转
在原有的平衡树中插入16这个节点,导致不平衡,先通过左单旋转调整使之成为右单旋转的模型,然后使之平衡,这个过程就称为先左后右双向旋转。
代码实现:
void RotateLR(AVLNode<Type> *&ptr)
{
AVLNode<Type> *subR = ptr;
AVLNode<Type> *subL = ptr->leftChild;
ptr = subL->rightChild;
subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
if(ptr->bf <= 0)
subL->bf = 0;
else
subL->bf = -1;
subR->leftChild = ptr->rightChild;
ptr->rightChild = subR;
if(ptr->bf == -1)
subR->bf = 1;
else
subR->bf = 0;
ptr->bf = 0;
}
4.先左后右双向旋转
在原有的平衡树中插入16这个节点,导致不平衡,先通过右单旋转调整使之成为左单旋转的模型,然后使之平衡,这个过程就称为先右后左双向旋转。
代码实现:
void RotateRL(AVLNode<Type> *&ptr)
{
AVLNode<Type> *subL = ptr;
AVLNode<Type> *subR = ptr->rightChild;
ptr = subR->leftChild;
subR->leftChild = ptr->rightChild;
ptr->rightChild = subR;
if(ptr->bf >=0)
subR->bf = 0;
else
subR->bf = 1;
subL->rightChild = ptr->leftChild;
ptr->leftChild = subL;
if(ptr->bf == 1)
subL->bf = -1;
else
subL->bf = 0;
ptr->bf = 0;
}