zoukankan      html  css  js  c++  java
  • AVL平衡二叉树的各种问题(Balanced Binary Tree)

    AVL树或者是一棵空树,或者是具有以下性质的非空二叉搜索树:

    1. 任一结点的左、右子树均为AVL树;

    2.根结点左、右子树高度差的绝对值不超过1.

    1.声明

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    typedef int ElementType;
    typedef struct AVLNode * AVLTree; //AVL树类型 
    struct AVLNode{
        ElementType Data;    //结点数据 
        AVLTree Left;        //左子树 
        AVLTree Right;        //右子树 
        int Height;         //树高 
    };
    View Code

    2.获取高度

    int GetHeight(AVLTree T){
        if(T) return max(GetHeight(T->Left ),GetHeight(T->Right )) + 1;
        else return 0;
    }
    View Code

    3.左单旋LL

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

    4.右单旋RR

    AVLTree SingleRightRotation(AVLTree A){
        AVLTree 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->Right ),A->Height ) + 1;
        return B;
    }
    View Code

    5.左-右双旋LR

    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);
    }
    View Code

    6.右-左双旋RL

    AVLTree DoubleRightLeftRotation(AVLTree A){
        A->Right = SingleLeftRotation(A->Right );
        return SingleRightRotation(A);
    }
    View Code

    7.AVL树的插入

    AVLTree Insert(AVLTree T, ElementType X){
        //将 X 插入AVL树 T 中,并且返回调整后的AVL树 
        if(! T){ //若插入空树,则新建包含一个结点的树 
            T = (AVLTree)malloc(sizeof(struct AVLNode));
            T->Data  = X;
            T->Height = 1;
            T->Left = T->Right = NULL;
        }
        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(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 X==T->Data 无需插入
        
        //更新树高 
        T->Height = max(GetHeight(T->Left ),GetHeight(T->Right )) + 1;
        return T;
    }
    View Code

    完整测试:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    typedef int ElementType;
    typedef struct AVLNode * AVLTree;
    struct AVLNode{
        ElementType Data;
        AVLTree Left;
        AVLTree Right;
        int Height; 
    };
    int GetHeight(AVLTree T){
        if(T) return max(GetHeight(T->Left ),GetHeight(T->Right )) + 1;
        else return 0;
    }
    AVLTree SingleLeftRotation(AVLTree A){
        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 SingleRightRotation(AVLTree A){
        AVLTree 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->Right ),A->Height ) + 1;
        return B;
    }
    AVLTree DoubleLeftRightRotation(AVLTree A){
        A->Left = SingleRightRotation(A->Left );
        return SingleLeftRotation(A);
    }
    AVLTree DoubleRightLeftRotation(AVLTree A){
        A->Right = SingleLeftRotation(A->Right );
        return SingleRightRotation(A);
    }
    AVLTree Insert(AVLTree T, ElementType X){
        if(! T){
            T = (AVLTree)malloc(sizeof(struct AVLNode));
            T->Data  = X;
            T->Height = 1;
            T->Left = T->Right = NULL;
        }
        else if(X < T->Data ){
            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(X > T->Data ){
            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);
        }
        T->Height = max(GetHeight(T->Left ),GetHeight(T->Right )) + 1;
        return T;
    }
    void LevelorderTravelsal(AVLTree BT){
        queue<AVLTree> q;
        AVLTree T;
        if(!BT) return;
        q.push(BT);
        while(!q.empty()){
            T=q.front();
            q.pop();
            cout<<T->Data <<" ";
            if(T->Left ) q.push(T->Left );
            if(T->Right ) q.push(T->Right );
        }
    } 
    int main(){
        int n; cin>>n;
        AVLTree T = NULL;
        for(int i=0;i<n;i++){
            int x; cin>>x;
            T = Insert(T, x);
        }
        LevelorderTravelsal(T);
    }
    View Code
  • 相关阅读:
    Linq To Sql 练习
    伪静态在webconfig中配置
    log4net.dll配置以及在项目中应用
    C#Windows服务安装
    .net平台推送ios消息
    asp.net下js调用session
    MAC地址泛洪攻击测试
    wifipineapple使用教程
    python程序的调试方法
    python import的用法
  • 原文地址:https://www.cnblogs.com/astonc/p/10088295.html
Copyright © 2011-2022 走看看