回 帖 发 新 帖 刷新版面

主题:[讨论]有关AVL树的平衡处理的小问题。

对严版的左平衡旋转处理函数有一些小疑问。
整体的描述如下:
typedef struct BSTNode {
    ElemType    data ;
    int             bf ;         //结点的平衡因子
    struct BSTNode *lchild , *rchild ;    //左、右孩子指针
}BSTNode , *BSTree ;

void R_Rotate (BSTree &p)    {
    //对以*p为根的二叉排序树作右旋转处理,处理之后p指向新的树根结点,即旋转
    //处理之前的左子树的根结点
    lc=p->lchild ;            //lc指向的*p的左子树根结点
    p->lchild=lc->rchild ;    //lc的右子树挂接为*p的左子树
    lc->rchild=p ; p=lc ;    //p指向新的根结点
}// R_Rotate
void L_Rotate (BSTree &p)    {
    //对以*p为根的二叉排序树作左旋处理,处理之后p指向新的树根结点,即旋转
    //处理之前的右子树的根结点
    rc=p->rchild ;            //rc指向的*p的右子树根结点
    p->rchild=rc->lchild ;    //rc左子树挂接为*p的右子树
    rc->lchild=p ; p=rc ;        //p指向新的根结点
}//L_Rotate

#define LH +1        //左高
#define EH 0        //等高
#define RH -1        //右高
Status InsertAVL (BSTree &T , ElemType e , Boolean &taller )    {
    //若在平衡二叉排序树T中不存在和e有相同关键字的结点,则插入一个数据元素
    //为e的新结点,并返回1,否则返回0。若因插入而使二叉排序树失去平衡,则作平衡
    //旋转处理,布尔变量taller反映T长高与否
    if (!T)     {//插入新结点,树“长高”,置taller为TRUE
        T=(BSTree)malloc(sizeof(BSTNode)); T->data=e ;
        T->lchild=T->rchild=NULL; T->bf=EH ; taller = TRUE ;
    }
    else {
        if (EQ(e.key , T->data.key))            //树中已存在和e有相同关键字的结点
            { taller=FALSE ; return 0 ; }        //则不插入
        if (LT(e.key , T->data.key))    {        //继续在*T的左子树中进行搜索
            if (!InsertAVL(T->lchild , e , taller)) return 0;    //未插入
            if (taller)                    //已插入到*T的左子树中且左子树“长高”
                switch ( T->bf )    {    //检查*T的平衡度
                    case LH:     //原本左子树比右子树高,需要作左平衡处理
                        LeftBalance(T) ; taller=FALSE ; break ;
                    case EH:        //原本左、右子树等高,现因左子树增高而使树增高
                        T->bf=LH ; taller=TRUE ; break ;
                    case RH:        //原本右子树比左子树高,现左、右子树等高
                        T->bf=EH ; taller=FALSE ; break ;
                }//switch(T->bf)
        }//if
        else {                        //继续在*T的左子树中进行搜索
            if(!InsertAVL(T->rchild , e , taller)) return 0 ;    //未插入
            if (taller)                    //已插入到*T的右子树中且右子树“长高”
                switch ( T->bf )    {    //检查*T的平衡度
                    case LH:     //原本左子树比右子树高,现左、右子树等高
                        T->bf=EH ; taller=FALSE ; break ;
                    case EH:        //原本左、右子树等高,现因右子树增高而使树增高
                        T->bf=RH ; taller=FALSE ; break ;
                    case RH:        //原本右子树比左子树高,需要作右平衡处理
                        RightBalance(T) ; taller=FALSE ; break ;
                }//switch(T->bf)
            }//else
    }//else
    return 1;
}//InsertAVL
void LeftBalance (BSTree &T)    {
    //对以指针T所指结点为根的二叉树作左平衡旋转处理,本算法结束时,指针T指向
    //新的根结点
    lc=T->lchild ;            //lc指向*T的左子树根结点
    switch (lc->bf)        {    //检查*T的左子树的平衡高度,并作相应平衡处理
        case LH:            //新结点插入在*T的左孩子的左子树上,要作单右旋处理
            T->bf=lc->bf=EH ;
            R_Rotate(T); break ;
        case RH:            //新结点插入在*T的左孩子的右子树上,要作双旋处理
            rd=lc->rchild ;     //rd指向*T的左孩子的右子树根
            switch (rd->bf)     {    //修改*T及其左孩子的平衡因子
                case LH: T->bf=RH ; lc->bf=EH ; break ;
                case EH: T->bf= lc->bf=EH ; break ;
                case RH: T->bf=EH ; lc->bf=LH ; break ;
            }// switch (rd->bf)
            rd->bf=EH;
            L_Rotate(T->lchild) ;        //对*T的左子树作左旋转处理
            R_Rotate(T) ;                //对*T作右旋转处理
    }// switch (lc->bf)
}//LeftBalance


最后的LeftBalance处理中 对于switch (rd->bf)的情况,严版描述是分了3类情况。但case EH貌似废的? 如果rd->bf如果插入后没作处理都是平衡的,说明以rd为根的子树高度没变化。那么自然不影响其祖先结点的平衡度了。

求指教~~

回复列表 (共1个回复)

沙发

是啊。程序运行到此时,根本不可能出现rd->bf = 0的情况。

我来回复

您尚未登录,请登录后再回复。点此登录或注册