zoukankan      html  css  js  c++  java
  • C/C++ 平衡二叉树笔记(AVL树)

    个人笔记,仅供复习

    1.概念

    1.1 背景:搜索树结点的不同插入次序,将导致不同深度和平均查找长度ASL


    1.2 平衡因子(Balance Factor,简称BF):BF(T) = h(L) - h(R),其中h(L)和h(R)分别为左、右子树高度。

    1.3 平衡二叉树(Balance Binary Tree)(AVL树)定义:

    • 空树
    • 任一结点左右子树高度差的绝对值不超过1,即|BF(T)|<=1

    1.4 代码实例:

    typedef struct AVLNode *Position;
    typedef Position AVLTree; /* AVL树类型 */
    struct AVLNode{
        int Data; /* 结点数据 */
        AVLTree Left;     /* 指向左子树 */
        AVLTree Right;    /* 指向右子树 */
        int Height;       /* 树高 */
    };

    1.5 平衡二叉树的高度能否达到log2(n)?

            设n(h)为高度为h的平衡二叉树的最少结点数。结点数最少时:


    斐波那契数列(Fn)对比:

    2.平衡二叉树的调整

    2.1 背景:当对平衡二叉树进行插入或删除操作时,可能会改变左右子树的高度,因此可能会破坏平衡性。所以需要在插入或删除操作后进行调整。

    2.2 四种调整情况:

    • RR旋转(右单旋)
    • LL旋转(左单旋)
    • LR旋转
    • RL旋转

    2.3 代码实例:

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

  • 相关阅读:
    guxh的python笔记一:数据类型
    guxh的python笔记三:装饰器
    guxh的python笔记十:包和模块
    guxh的python笔记六:类的属性
    guxh的python笔记四:迭代
    流畅的python笔记
    spring面试大全
    Spring面试问答
    Hibernate的10个常见面试问题及答案
    reflect 机制
  • 原文地址:https://www.cnblogs.com/long98/p/10352235.html
Copyright © 2011-2022 走看看