AVL 平衡树源码笔记

avltree.h

typedef int ElementType;

/* START: fig4_35.txt */
#ifndef _AvlTree_H
#define _AvlTree_H

struct AvlNode;
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree;

AvlTree MakeEmpty( AvlTree T );
Position Find( ElementType X, AvlTree T );
Position FindMin( AvlTree T );
Position FindMax( AvlTree T );
AvlTree Insert( ElementType X, AvlTree T );
AvlTree Delete( ElementType X, AvlTree T );
ElementType Retrieve( Position P );

#endif  /* _AvlTree_H */
/* END */

avltree.c

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

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;
}

// 查找元素,和 BST 操作相同
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) // Lhs --> Left hand side  Rhs --> Right hand side
{
    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 */
//  LL 单旋转
static Position
SingleRotateWithLeft(Position K2)
{
    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 */
// RR 单旋转
static Position
SingleRotateWithRight(Position K1)
{
    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 */
// LR 双旋转
static Position
DoubleRotateWithLeft(Position K3)
{
    /* Rotate between K1 and K2 */
    K3->Left = SingleRotateWithRight(K3->Left); // 先进行 RR 旋转

    /* Rotate between K3 and K2 */
    return SingleRotateWithLeft(K3); // 然后进行 LL 旋转
}
/* 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 */
// RL 双旋转
static Position
DoubleRotateWithRight(Position K1)
{
    /* 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) // 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) // 平衡因子为 2
            if (X < T->Left->Element) // LL 情况
                T = SingleRotateWithLeft(T);
            else // LR 情况
                T = DoubleRotateWithLeft(T);
    } else if (X > T->Element)
    {
        T->Right = Insert(X, T->Right);
        if (Height(T->Right) - Height(T->Left) == 2) // RR 情况
            if (X > T->Right->Element)
                T = SingleRotateWithRight(T);
            else // RL 情况
                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;
}

/* END */
// 这里应该作 lazy delete,但是这里并没有实现任何删除操作
AvlTree
Delete(ElementType X, AvlTree T)
{
    printf("Sorry; Delete is unimplemented; %d remains
", X);
    return T;
}

// 取出节点的元素
ElementType
Retrieve(Position P)
{
    return P->Element;
}

main.c(testavl.c 测试函数)

#include "avltree.h"
#include <stdio.h>

int main()
{
    AvlTree T;
    Position P;
    int i;
    int j = 0;

    T = MakeEmpty( NULL );
    for( i = 0; i < 50; i++, j = ( j + 7 ) % 50 ) // 插入数据
        T = Insert( j, T );
    for( i = 0; i < 50; i++ ) // 测试上面的插入操作是否正确
        if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )
            printf( "Error at %d
", i );

    // 注释中的时测试删除操作,但是我们并没有实现删除操作,所以暂时不表
    /* for( i = 0; i < 50; i += 2 )
           T = Delete( i, T );

       for( i = 1; i < 50; i += 2 )
           if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )
               printf( "Error at %d
", i );
       for( i = 0; i < 50; i += 2 )
           if( ( P = Find( i, T ) ) != NULL )
               printf( "Error at %d
", i );
   */
    // 测试取出最小值和最大值的操作
    printf( "Min is %d, Max is %d
", Retrieve( FindMin( T ) ),
            Retrieve( FindMax( T ) ) );

    return 0;
}

测试结果:

20201016005739

定义错误的头文件 fatal.h

#include <stdio.h>
#include <stdlib.h>

#define Error(Str)        FatalError( Str )
#define FatalError(Str)   fprintf( stderr, "%s
", Str ), exit( 1 )
原文地址:https://www.cnblogs.com/fanlumaster/p/13824006.html