1. 程式人生 > >資料結構MOOC|平衡二叉樹

資料結構MOOC|平衡二叉樹

ASL平均查詢長度:



平衡因子BF:BF(T)=hL-hR

平衡二叉樹(AVL樹):空樹或者任一節點左、右子樹高度差的絕對值不超過1,即|BF(T)|<=1



RR旋轉:


LL旋轉:


LR旋轉:


RL旋轉:


typedef struct AVLNode *Position;
typedef Position AVLTree; /* AVL樹型別 */
struct AVLNode{
    ElementType Data; /* 結點資料 */
    AVLTree Left;     /* 指向左子樹 */
    AVLTree Right;    /* 指向右子樹 */
    int Height;       /* 樹高 */
};
 
int Max ( int a, int b )
{
    return a > b ? a : b;
}
 
AVLTree SingleLeftRotation ( AVLTree A )
{ /* 注意:A必須有一個左子結點B */
  /* 將A與B做左單旋,更新A與B的高度,返回新的根結點B */     
 
    AVLTree B = A->Left;
    A->Left = B->Right;
    B->Right = A;
    A->Height = Max( GetHeight(A->Left), GetHeight(A->Right) ) + 1;
    B->Height = Max( GetHeight(B->Left), A->Height ) + 1;
  
    return B;
}
 
AVLTree DoubleLeftRightRotation ( AVLTree A )
{ /* 注意:A必須有一個左子結點B,且B必須有一個右子結點C */
  /* 將A、B與C做兩次單旋,返回新的根結點C */
     
    /* 將B與C做右單旋,C被返回 */
    A->Left = SingleRightRotation(A->Left);
    /* 將A與C做左單旋,C被返回 */
    return SingleLeftRotation(A);
}
 
/*************************************/
/* 對稱的右單旋與右-左雙旋請自己實現 */
/*************************************/
 
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 = SingleLeftRotation(T);      /* 左單旋 */
            else 
               T = DoubleLeftRightRotation(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 = SingleRightRotation(T);     /* 右單旋 */
            else 
               T = DoubleRightLeftRotation(T); /* 右-左雙旋 */
    } /* else if (插入右子樹) 結束 */
 
    /* else X == T->Data,無須插入 */
 
    /* 別忘了更新樹高 */
    T->Height = Max( GetHeight(T->Left), GetHeight(T->Right) ) + 1;
     
    return T;
}