zoukankan      html  css  js  c++  java
  • 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 )
    
  • 相关阅读:
    win10自动休眠解决方法
    创世纪游戏、黄金分割比
    placeholder和assign速度对比
    内耗
    windows下编写dll
    北航院系和数字的对应关系
    maven Could not resolve dependencies
    java9模块不可见问题
    maven-dependencies插件的模拟实现
    Freemarker简单封装
  • 原文地址:https://www.cnblogs.com/fanlumaster/p/13824006.html
Copyright © 2011-2022 走看看