AVLTrees

AVL Trees

Target

Speed up dynamic searching(insert or delete all the time)

Definition

An empty binary tree is height balanced. If T is a nonempty binary tree with TL and TR as its left and right subtrees, then T is height balanced if TL and TR are height balanced, and |hL - hR| <= 1 where hL and hR are the heights of TL and TR, respectively.

Rotations

Single Rotation

LL Rotation

在这里插入图片描述

Apr is trouble maker, Mar is trouble finder. Apr locates in Mar’s left subtree’s left subtree.

AVLTree LL_Rotation( AVLTree A )
{ /* 注意:A必须有一个左子结点B */
  /* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */     

    AVLTree B = A->Left;	//保存A的左节点
    A->Left = B->Right;		//将B的右节点放到A的左节点上
    B->Right = A;			//B的右节点连上A
    A->Height = Max( GetHeight(A->Left), GetHeight(A->Right) ) + 1;
    B->Height = Max( GetHeight(B->Left), A->Height ) + 1;
 
    return B;
}
RR Rotation

在这里插入图片描述

Nov is trouble maker, Mar is trouble finder. Nov locates in Mar’s right subtree’s right subtree.

AVLTree RR_Rotation( AVLTree A )
{ /* 注意:A必须有一个右子结点B */
  /* 将A与B做右单旋,更新A与B的高度,返回新的根结点B */     

    AVLTree B = A->Right;	//保存A的右节点
    A->Right = B->Left;		//将B的右节点放到A的左节点上
    B->Left = A;			//B的右节点连上A
    A->Height = Max( GetHeight(A->Left), GetHeight(A->Right) ) + 1;
    B->Height = Max( GetHeight(B->Left), A->Height ) + 1;
 
    return B;
}

Double Rotation

LR Rotation

在这里插入图片描述

Jan is trouble maker, May is trouble finder. Jan locates in May’s left subtree’s right subtree. Starting from May, the node is promoted to the position of May two levels down, and May and its right subtree are taken as the right subtree of the node.(从May开始向下两层,将这个节点提升到May的位置,将May及其右子树作为该节点的右子树)

AVLTree LR_Rotation ( AVLTree A )
{ /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
  /* 将A、B与C做两次单旋,返回新的根结点C */
    
    /* 将B与C做右单旋,C被返回 */
    A->Left = RR_Rotation(A->Left);
    /* 将A与C做左单旋,C被返回 */
    return LL_Rotation(A);
}
RL Rotation

在这里插入图片描述

Feb is trouble maker, Aug is trouble finder. Feb locates in Aug’s right subtree’s left subtree. Starting from Aug, the node is promoted to the position of Aug two levels down, and Aug and its left subtree are taken as the left subtree of the node.(从Aug开始向下两层,将这个节点提升到Aug的位置,将Aug及其左子树作为该节点的左子树)

AVLTree RL_Rotation ( AVLTree A )
{ /* 注意:A必须有一个右子结点B,且B必须有一个左子结点C */
  /* 将A、B与C做两次单旋,返回新的根结点C */
    
    /* 将B与C做左单旋,C被返回 */
    A->Right = LL_Rotation(A->Right);
    /* 将A与C做右单旋,C被返回 */
    return RR_Rotation(A);
}
Methods

Find trouble maker and trouble finder, judge their positional relationship:

  1. If a single rotation can be down, we can start from the trouble finder, count down one layer, and promote this node to the position of the trouble finder.(如果只进行一次旋转就可以搞定的话,我们可以从trouble finder出发,向下数一层,将 这个节点提升到trouble finder的位置)

  2. If we need to rotate twice to get it done, we can start from the trouble finder, count down two layers, and lift this node to the position of the trouble finder.(如果要进行两次旋转才可以搞定,我们可以从trouble finder出发,向下数两层,将这个节点提升到trouble finder的位置)

Insertion

AVLTree Insert( AVLTree T, ElementType X )
{ /* 将X插入AVL树T中,并且返回调整后的AVL树 */
    if ( !T ) { /* 若插入空树,则新建包含一个结点的树 */
        T = (AVLTree)malloc(sizeof(struct AVLNode));
        T->Data = X;
        T->Height = 0;
        T->Left = T->Right = NULL;
    } /* if (插入空树) 结束 */

    else if ( X < T->Data ) {
        /* 插入T的左子树 */
        T->Left = Insert( T->Left, X);
        /* 如果需要左旋 */
        if ( GetHeight(T->Left)-GetHeight(T->Right) == 2 )
            if ( X < T->Left->Data ) 
               T = LL_Rotation(T);      /* 左单旋 */
            else 
               T = LR_Rotation(T); /* 左-右双旋 */
    } /* else if (插入左子树) 结束 */
    
    else if ( X > T->Data ) {
        /* 插入T的右子树 */
        T->Right = Insert( T->Right, X );
        /* 如果需要右旋 */
        if ( GetHeight(T->Left)-GetHeight(T->Right) == -2 )
            if ( X > T->Right->Data ) 
               T = RR_Rotation(T);     /* 右单旋 */
            else 
               T = RL_Rotation(T); /* 右-左双旋 */
    } /* else if (插入右子树) 结束 */

    /* else X == T->Data,无须插入 */

    /* 别忘了更新树高 */
    T->Height = Max( GetHeight(T->Left), GetHeight(T->Right) ) + 1;
    
    return T;
}

Deletion

在这里插入图片描述

As shown in the above figure, after deleting a node, there may be RE type or LE type imbalances, but the adjustment method is the same as that of RR type or LL type imbalances.(如上图所示,删除节点后可能会出现RE型或LE型失衡,但是调整方式和RR型或LL型失衡的调整方式一样)

AVLTree Delete( AVLTree T, ElementType X ) 
{ 
    Position Tmp; 

    if( !T ) 
        printf("要删除的元素未找到"); 
    else {
        if( X < T->Data ){ 
            T->Left = Delete( T->Left, X );   /* 从左子树递归删除 */
            if( GetHeight(T->Right) - GetHeight(T->Left) == 2 ){
                if( GetHeight(T->Right->Right) >= GetHeight(T->Right->Left))	//RR型或RE型失衡
                    T = RR_Rotation(T);
                else
                    T = RL_Rotation(T);		//RL型失衡
            }
        }
        else if( X > T->Data ){ 
            T->Right = Delete( T->Right, X ); /* 从右子树递归删除 */
            if( GetHeight(T->Left) - GetHeight(T->Right) == 2){
                if( GetHeight(T->Left->Left) >= GetHeight(T->Left->Right))	//LL型或LE型失衡
                    T = LL_Rotation(T);
                else
                    T = LR_Rotation(T);	//LR型失衡
            }
        }
        else { /* T就是要删除的结点 */
            /* 如果被删除结点有左右两个子结点 */ 
            if( T->Left && T->Right ) {
                /* 从右子树中找最小的元素填充删除结点 */
                Tmp = FindMin( T->Right );
                T->Data = Tmp->Data;
                /* 从右子树中删除最小元素 */
                T->Right = Delete( T->Right, T->Data );
            }
            else { /* 被删除结点有一个或无子结点 */
                Tmp = T; 
                if( !T->Left )       /* 只有右孩子或无子结点 */
                    T = T->Right; 
                else                   /* 只有左孩子 */
                    T = T->Left;
                free( Tmp );
            }
        }
    }
    T->Height = Max( GetHeight(T->Left), GetHeight(T->Right) ) + 1;
    return T;
}

参考

MOOC–Advanced Data Structures and Algorithm Analysis
AVL树(查找、插入、删除)——C语言

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值