AVL旋转操作详解

第一种旋转方式是LL类型,如图所示:


k2的左边比右边高了2,说明X的高度比Z高1
代码如下

void LL_Rotate(AVLNode* &p)  
{   
    AVLNode * lc = NULL;  
    lc  = p->lchild;     //lc指向p的左子树根结点  
    p->lchild = lc->rchild;   //lc的右子树挂接为p的左子树   
    lc->rchild = p;  
    p = lc;                 //p指向新的根结点   
}  
思路就是把k1放在根结点,然后把k1的右子树Y挂在k2上,k2挂在k1右边。
平衡因子改变:如果Y和X等高,那么k1平衡因子为-1,k2平衡因子为1,如果X比Y高,那么k1和k2平衡因子都为0。
第二种旋转方式为LR旋转,如图所示:


其中B和C至少有一个和D是一样高(图中取了平均)。LR旋转的本质是先进行一次RR旋转变成LL类型的树,然后再进行一次LL旋转。代码如下所示:

void LR_Rotate(AVLNode* &p)
{
	RR_Rotate(p->lchild);
	LL_Rotate(p);
}
平衡因子调整:如果B比C高,那么B和A是一样高的,那么k1平衡因子为0,k3平衡因子为-1.同理,如果C比B高,那么k3平衡因子为0,k1平衡因子为-1.如果B和C一样高,那么k1和k2的平衡因子都为0。k3恒为0。
根据LL旋转和LR旋转就可以写出AVL树的左边平衡代码了:
void leftBalance(AVLNode* &t)  
{  
    AVLNode* lc = NULL;  
    AVLNode* rd = NULL;  
    lc = t->lchild;  
    switch(lc->bf)  
    {  
        case LH:                    //LL旋转   
            t->bf = EH;  
            lc->bf = EH;  
            LR_Rotate(t);          
            break;  
          
        case EH:                    //deleteAVL需要,insertAVL用不着   
            t->bf = LH;  
            lc->bf = RH;  
            LR_Rotate(t);  
            break;  
          
        case RH:                    //LR旋转   
            rd = lc->rchild;  
            switch(rd->bf)  
            {  
                case LH:  
                    t->bf = RH;  
                    lc->bf = EH;  
                    break;    
                case EH:  
                    t->bf = EH;  
                    lc->bf = EH;  
                    break;  
                case RH:  
                    t->bf = EH;  
                    lc->bf = LH;  
                    break;  
            }  
            rd->bf = EH;  
            LR_Rotate(t);  
            break;  
    }  
}  

第三种旋转方式为RR旋转




分析方法和LL旋转一样,代码如下

void RR_Rotate(AVLNode* &p)  
{  
    AVLNode * rc = NULL;  
    rc = p->rchild;          //rc指向p的右子树根结点  
    p->rchild = rc->lchild;//rc的左子树挂接为p的右子树   
    rc->lchild = p;  
    p = rc;                 //p指向新的根结

第四种方式是RL旋转,如图所示:


分析方式和LR旋转类似,平衡因子也要看BC和A的高度情况。
代码如下:

void RL_Rotate(AVLNode* &p)
{
	LL_Rotate(p->rchild);
	RR_Rotate(p);
}
由此可以写出右平衡代码
void rightBalance(AVLNode* &t)  
{  
    AVLNode* rc = NULL;  
    AVLNode *ld = NULL;  
      
    rc = t->rchild;  
    switch(rc->bf)  
    {  
        case LH:                //RL旋转   
            ld = rc->lchild;   
            switch(ld->bf)  
            {  
                case LH:  
                    t->bf = EH;  
                    rc->bf = RH;  
                    break;  
                case EH:  
                    t->bf = EH;  
                    rc->bf = EH;  
                    break;  
                case RH:  
                    t->bf = LH;  
                    rc->bf = EH;  
                    break;  
            }  
            ld->bf = EH;  
            RL_Rotate(t);  
            break;  
              
        case EH:                //deleteAVL需要,insertAVL用不着   
            t->bf = RH;  
            rc->bf = LH;  
            L_Rotate(t);  
            break;  
                  
        case RH:                //RR旋转   
            t->bf = EH;  
            rc->bf = EH;  
            RR_Rotate(t);  
            break;  
    }  
}  

本文代码参考了:http://blog.csdn.net/sysu_arui/article/details/7897017

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值