AVL树C实现

#include "avltree.h"
#include "fatal.h"
#include <stdlib.h>

#include <math.h>


typedef struct AvlNode *AvlTree;

typedef struct AvlNode *Position;

struct AvlNode
{
    ElementType Element;
    AvlTree  Left;
    AvlTree  Right;
    int      Height;
};

AvlTree
MakeEmpty( AvlTree T )
{
    if( T != NULL )
    {
        MakeEmpty( T->Left );
        MakeEmpty( T->Right );
        free( T );
    }
    return NULL;
}

Position
Find( ElementType X, AvlTree T )
{
    if( T == NULL )
        return NULL;
    if( X < T->Element )
        return Find( X, T->Left );
    else if( X > T->Element )
        return Find( X, T->Right );
    else
        return T;
}

Position
FindMin( AvlTree T )
{
    if( T == NULL )
        return NULL;
    else if( T->Left == NULL )
        return T;
    else
        return FindMin( T->Left );
}

Position
FindMax( AvlTree T )
{
    if( T != NULL )
        while( T->Right != NULL )
            T = T->Right;

    return T;
}

/* START: fig4_36.txt */
static int
Height( Position P )
{
    if( P == NULL )
        return -1;
    else
        return P->Height;
}
/* END */

static int
Max( int Lhs, int Rhs )
{
    return Lhs > Rhs ? Lhs : Rhs;
}

/* START: fig4_39.txt */
/* This function can be called only if K2 has a left child */
/* Perform a rotate between a node (K2) and its left child */
/* Update heights, then return new root */

static Position
SingleRotateWithLeft( Position K2 )  // LL
{
    //printf("SingleRotateWithLeft \n");
    Position K1;

    K1 = K2->Left;
    K2->Left = K1->Right;
    K1->Right = K2;

    K2->Height = Max( Height( K2->Left ), Height( K2->Right ) ) + 1;
    K1->Height = Max( Height( K1->Left ), K2->Height ) + 1;

    return K1;  /* New root */
}
/* END */

/* This function can be called only if K1 has a right child */
/* Perform a rotate between a node (K1) and its right child */
/* Update heights, then return new root */

static Position
SingleRotateWithRight( Position K1 )  //RR
{
    //printf("SingleRotateWithRight \n");
    Position K2;

    K2 = K1->Right;
    K1->Right = K2->Left;
    K2->Left = K1;

    K1->Height = Max( Height( K1->Left ), Height( K1->Right ) ) + 1;
    K2->Height = Max( Height( K2->Right ), K1->Height ) + 1;

    return K2;  /* New root */
}

/* START: fig4_41.txt */
/* This function can be called only if K3 has a left */
/* child and K3's left child has a right child */
/* Do the left-right double rotation */
/* Update heights, then return new root */

static Position
DoubleRotateWithLeft( Position K3 )   // LR
{
    /* Rotate between K1 and K2 */
    K3->Left = SingleRotateWithRight( K3->Left );

    /* Rotate between K3 and K2 */
    return SingleRotateWithLeft( K3 );
}
/* END */

/* This function can be called only if K1 has a right */
/* child and K1's right child has a left child */
/* Do the right-left double rotation */
/* Update heights, then return new root */

static Position
DoubleRotateWithRight( Position K1 )  //RL
{
    /* Rotate between K3 and K2 */
    K1->Right = SingleRotateWithLeft( K1->Right );

    /* Rotate between K1 and K2 */
    return SingleRotateWithRight( K1 );
}


/* START: fig4_37.txt */
AvlTree
Insert( ElementType X, AvlTree T )
{
    if( T == NULL )
    {
        /* Create and return a one-node tree */
        T = malloc( sizeof( struct AvlNode ) );
        if( T == NULL )
            FatalError( "Out of space!!!" );
        else
        {
            T->Element = X;
            T->Height = 0;
            T->Left = T->Right = NULL;
        }
    }
    else if( X < T->Element )
    {
        T->Left = Insert( X, T->Left );
        if( Height( T->Left ) - Height( T->Right ) == 2 )
            if( X < T->Left->Element )
                T = SingleRotateWithLeft( T );
            else
                T = DoubleRotateWithLeft( T );
    }
    else if( X > T->Element )
    {
        T->Right = Insert( X, T->Right );
        if( Height( T->Right ) - Height( T->Left ) == 2 )
            if( X > T->Right->Element )
                T = SingleRotateWithRight( T );
            else
                T = DoubleRotateWithRight( T );
    }
    /* Else X is in the tree already; we'll do nothing */

    T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
    return T;
}


/* 对单个结点进行AVL调整 */
static Position
Rotate4Delete( Position T )
{
    if( Height(T->Left) - Height(T->Right) == 2 )
    {
        //比较T左孩子的左右子树高度来决定采取哪种旋转方式
        if( Height(T->Left->Left) > Height(T->Left->Right) )
        {
            T = SingleRotateWithLeft( T );
        }
        else
        {
            T = DoubleRotateWithLeft( T ); /*LR*/
        }
    }

    if( Height(T->Right) - Height(T->Left) == 2)
    {
        if( Height(T->Right->Right) > Height(T->Right->Left) )
        {
            T = SingleRotateWithRight( T );   //RR
        }
        else
        {
            T = DoubleRotateWithRight( T );  // RL

        }
    }
    return T;
}


AvlTree
Delete( ElementType X, AvlTree T )
{
    // printf( "Sorry; Delete is unimplemented; %d remains\n", X );
    if( T == NULL )
        return NULL;

    if( X == T->Element )
    {
        //此节点左右儿子都不为空
        if( T->Left != NULL & T->Right != NULL )
        {
            Position tmp = T->Right;
            while( tmp->Left != NULL )
            {
                tmp = tmp->Left;
            }
            T->Element = tmp->Element;
            T->Right = Delete( tmp->Element , T->Right);
            T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
        }
        else    //此节点有1个或0个子儿子
        {
            Position tmp = T;
            T = ( T->Left != NULL ) ? T->Left : T->Right;
            /*
            if(T->Left == NULL){
                T = T->Right;
            }else if(t->Right == NULL){
                T = T->Left;
            }
            */
            free( tmp );
            tmp = NULL;
        }
        return T;
    }
    else if( X < T->Element )
    {
        T->Left = Delete( X, T->Left);
        if(T->Left != NULL)
        {
            T->Left = Rotate4Delete( T->Left );
        }
    }
    else
    {
        T->Right = Delete(  X , T->Right);
        if( T->Right != NULL )
        {
            T->Right = Rotate4Delete( T->Right );
        }
    }
    T->Height = Max( Height( T->Left ), Height( T->Right ) ) + 1;
    if( T != NULL )
    {
        T = Rotate4Delete( T );
    }
    return T;
}

ElementType
Retrieve( Position P )
{
    if( NULL != P)
    {
        return P->Element;
    }
    else
    {
        return NULL;
    }
}

void PreOrder(AvlTree T)
{
    if(T != NULL)
    {
        printf("current element is %d, height is %d, left child is %d ,right child is %d \n", Retrieve(T), Height(T), Retrieve(T->Left), Retrieve(T->Right));
        PreOrder(T->Left);
        PreOrder(T->Right);
    }
}

/*左子树和右子树高度差小于或者等于1*/
int isAvlTree( AvlTree T ){
    if( T != NULL )
    {
        if( abs(Height(T->Left) - Height(T->Right)) < 2)
        {
            isAvlTree(T->Left);
            isAvlTree(T->Right);
            return 1;
        }
        return 0;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值