通俗易懂看AVL树


平衡因子计算:二叉树上左子树深度减去右子树深度的值称为平衡因子BF。也可以看作是左子树高度减去右子树高度。




改进二叉排序树的结点结构,增加一个BF,存储平衡因子:

typedef struct BitNode
{
    int data;
    int BF;
    struct BitNode *left,*right;
}BitNode,*BiTree;


对于右旋操作:

void R_Rotate(BiTree *p)//ÓÒÐýת
{
    BiTree L=(*P)->left;
    (*p)->left=L->right;
    L->right=(*p);
    (*p)=L;
}

左旋类似,不再重复。

对于左平衡旋转出力的函数代码:

void leftBalance(BiTree *T)
{
    //左平衡旋转的处理
    BiTree L,Lr;
    L=(*T)->left;
    switch(L->BF)
    {
    case LH://左边高,情况1,直接右旋实现平衡
        (*T)->BF=L->BF=EH;
        R_Rotate(T);
        break;
    case RH:
        Lr=L->right;
        switch(Lr->BF)
        {
        case LH:
            (*T)->BF=RH;//情况2
            L->BF=EH;
            break;
        case EH:
            (*T)->BF=EH;//情况3
            L->BF=EH;
            break;
        case RH:
            (*T)->BF=EH;//情况4
            L->BF=LH;
            break;
        }
        Lr->BF=EH;//旋转平衡后Lr变为根节点;
        L_Rotate(&(*T)->left);
        R_Rotate(T);
    }

}
情况1为连续两次左旋,比较简单,略,2,3,4如下图,画的有些丑,但是能看懂,注意平衡因子的变化。





平衡二叉树的建立:


int InsertAVL(BiTree *T,int e,int *taller)
//taller用来判断树是否长高
{
    if(!*T)//如果不存在该节点,创建节点
    {
        *T=(BiTree)malloc(sizeof(BitNode));
        (*T)->data=e;
        (*T)->left=(*T)->right=NULL;
        (*T)->BF=EH;
        *taller=true;
    }
    else
    {
        if((*T)->data==e)
        {
            *taller=false;
            return false;

        }
        if(e<(*T)->data)
        {
            if(!InsertAVL(&(*T)->left,e,taller))
            {
                return false;
            }
            if(taller)
            {
        case LH:
            leftBalance(T);
            *taller=false;
            break;
        case EH:
            (*T)->BF=LH;
            *taller=true;
            break;
        case RH:
            (*T)->BF=EH;
            *taller=false;
            break;
            }
        }
        else
        {
            if(!InsertAVL(&(*T)->right,e,taller))
            {
                return false;
            }
            if(taller)
            {
        case LH:
            (*T)->BF=EH;
            *taller=false;
            break;
        case EH:
            (*T)->BF=RH;
            *taller=true;
            break;
        case RH:
           rightBalance(T);
           *taller=false;
            break;
            }
        }


    }
    return true;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值