• 算法与数据结构——AVL树(平衡二叉树)


    定义

    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;
    }
    int GetHeight(Position T)
    {
        int hr, hl;
        if (!T)
        {
            return 0;
        }
        hl = GetHeight(T->Left);
        hr = GetHeight(T->Right);
        return (hl > hr) ? ++hl : ++hr;
    }
    

    实现功能的主要函数

    调整函数

    Position SingleRoateWithLeft(Position A)
    {
        Position B;
        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), GetHeight(B->Right)) + 1;
        return B;//new node
    }
    //右单旋
    Position SingleRoateWithRight(Position A)
    {
        Position B;
        B = A->Right;
        A->Right = B->Left;
        B->Left = A;
        A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
        B->Height = Max(GetHeight(B->Left), GetHeight(B->Right)) + 1;
        return B;
    }
    //右左双旋
    Position DoubleRoateWithLeft(Position A)
    {
        A->Left = SingleRoateWithRight(A->Left);
        return SingleRoateWithLeft(A);
    }
    //左右双旋
    Position DoubleRoateWithRight(Position A)
    {
        A->Right = SingleRoateWithLeft(A->Right);
        return SingleRoateWithRight(A);
    }
    

    插入函数(兼具建树功能)

    AVLTree Insert(ElementType X, AVLTree T)
    {
        if (T == NULL)
        {
            T = new AVLNode;
            T->Data = X;
            T->Left = T->Right = NULL;
            T->Height = 0;
        }
        else if (X < T->Data)
        {
            T->Left = Insert(X, T->Left);
            if (GetHeight(T->Left) - GetHeight(T->Right) == 2)
            {
                if (X < T->Left->Data)
                {
                    T = SingleRoateWithLeft(T);
                }
                else
                {
                    T = DoubleRoateWithLeft(T);
                }
            }
        }
        else
        {
            T->Right = Insert(X, T->Right);
            if (GetHeight(T->Right) - GetHeight(T->Left) == 2)
            {
                if (X > T->Right->Data)
                {
                    T = SingleRoateWithRight(T);
                }
                else
                {
                    T = DoubleRoateWithRight(T);
                }
            }
    
        }
        T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1;
        return T;
    }
    

    删除函数

    删除函数和插入函数很像,删除的情况要考虑好。图解参考

    AVLTree Delete(ElementType X, AVLTree T)
    {
        if (T == NULL)
        {
            return NULL;
        }
        if (X < T->Data)
        {
            T->Left = Delete(X, T->Left);
        }
        else if (X > T->Data)
        {
            T->Right = Delete(X, T->Right);
        }
        else
        {
            if (T->Left)
            {
               AVLTree tmp= FindMax(T->Left);
               T->Data = tmp->Data;
               T->Left = Delete(tmp->Data, T->Left);
            }
            else if (T->Right)
            {
                AVLTree tmp = FindMin(T->Right);
                T->Data = tmp->Data;
                T->Right = Delete(tmp->Data, T->Right);
            }
            else
            {
                free(T);
                return NULL;
            }
        }
        if (GetHeight(T->Left) - GetHeight(T->Right) == 2)
        {
            if (GetHeight(T->Left->Left)>GetHeight(T->Left->Right))
            {
                T = SingleRoateWithLeft(T);
            }
            else
            {
                T = DoubleRoateWithLeft(T);
            }
        }
        else if (GetHeight(T->Right) - GetHeight(T->Left) == 2)
        {
            if (GetHeight(T->Right->Right) > GetHeight(T->Right->Left))
            {
                T = SingleRoateWithRight(T);
            }
            else
            {
                T = DoubleRoateWithRight(T);
            }
        }
        
        T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1;
        return T;
    }
    

    其他函数

    VLTree 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->Data)
        {
            return Find(X,T->Left);
        }
        else if(X>T->Data)
        {
            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)
        {
            return NULL;
        }
        else if(T->Right==NULL)
        {
            return T;
        }
        else
        {
            return FindMax(T->Right);
        }
    }
    

    深度和高度

    void showHeight(int a,Position T)
    {
    
         if (T == NULL)
         {
             return;
         }
         showHeight(a,T->Left);
         cout << T->Height << ' ';
         showHeight(a,T->Right);
    }
      void showdeep(int depth,Position T)
      {
         if (T == NULL) return;
          if (T)
          {
              
              showdeep(depth + 1, T->Left);
              cout << depth+1<<' ';
              showdeep(depth + 1, T->Right);
          }
      }
    
  • 相关阅读:
    Excel 向程序发送命令时出现问题
    JavaScript中undefined,null,NaN的区别
    MYSQL查询优化(一)
    win7 去除任务栏上出现的过期图标
    InnoDB与MyISAM区别
    form表单 按回车自动提交 实现方式
    多线程下载图片
    MySQL启动不了,InnoDB: autoextending data file .\ibdata1 is of a different size 78592 pages (rounded down to MB) than specified in the .cnf file: initial 131072 pages, max 0 (relevant if nonzero) pages!
    Net EF to MySQL生成edmx文件时报错:StrongTypingException:表“TableDetails"中列“IsPrimaryKey"的值为DBNull
    DataTable转置
  • 原文地址:https://www.cnblogs.com/wangmou-233-1024-com/p/13887229.html
Copyright © 2020-2023  润新知