zoukankan      html  css  js  c++  java
  • PTA 5-6 Root of AVL Tree (25)

    题目:http://pta.patest.cn/pta/test/16/exam/4/question/668

    PTA - Data Structures and Algorithms (English) - 5-6

    An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.

    LL:RR:

    RL:                                  

    LR:                         

    Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains a positive integer N (≤20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.

    Output Specification:

    For each test case, print the root of the resulting AVL tree in one line.

    Sample Input 1:
    5
    88 70 61 96 120
    
    Sample Output 1:
    70
    
    Sample Input 2:
    7
    88 70 61 96 120 90 65
    
    Sample Output 2:
    88

    分析:

    1. 树的结点结构

    typedef struct node
    {
    int data;
    node* left;
    node* right;
    int height;
    }AVLTreeNode,*AVLTree;
    

    2. 函数声明

    int GetHeight(AVLTree A) //获取当前树高
    int Max(int x,int y)     //用于更新树高
    //以下操作返回调整后的AVL树
    AVLTree SingleL_Rotation(AVLTree A)    //左单旋:LL
    AVLTree SingleR_Rotation(AVLTree A)    //右单旋:RR
    AVLTree DoubleLR_Rotation(AVLTree A)   //右左双旋:RL
    AVLTree DoubleRL_Rotation(AVLTree A)   //左右双旋:LR
    AVLTree AVL_Insertion(int x,AVLTree T) //将x插入AVL树T中
    

    3. 函数实现 (以左旋为例):

    //左单旋:LL
    AVLTree SingleL_Rotation(AVLTree A)
    {
        //!注:A必须有一个左子节点B
        //!左单旋后,更新A和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;
    }
    //左右双旋;LR
    AVLTree DoubleLR_Rotation(AVLTree A)
    {
        //!注:A必须有一个左子结点B,且B必须有一个右子节点C
        //!做两次单旋,返回新的根节点:C
    
        A->left=SingleR_Rotation(A->left); //!B和C做右单旋,返回C
        return SingleL_Rotation(A); //!A和做左单旋,返回C
    }
    

    完整代码:

    #include <iostream>
    using namespace std;
    
    typedef struct node
    {
        int data;
        node* left;
        node* right;
        int height;
    }AVLTreeNode,*AVLTree;
    
    int GetHeight(AVLTree A)
    {
        if(A==NULL)return -1;
        return A->height;
    }
    int Max(int x,int y)
    {
       return (x>y)?x:y;
    }
    
    //!左单旋:LL
    AVLTree SingleL_Rotation(AVLTree A)
    {
        //!注:A必须有一个左子节点B
        //!左单旋后,更新A和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;
    }
    //!右单旋:RR
    AVLTree SingleR_Rotation(AVLTree A)
    {
        AVLTree C=A->right;
        A->right=C->left;
        C->left=A;
        A->height=Max(GetHeight(A->left),GetHeight(A->right))+1;
        C->height=Max(A->height,GetHeight(C->right))+1;
        return C;
    }
    //!左右双旋;LR
    AVLTree DoubleLR_Rotation(AVLTree A)
    {
        //!注:A必须有一个左子结点B,且B必须有一个右子节点C
        //!做两次单旋,返回新的根节点:C
    
        A->left=SingleR_Rotation(A->left); //!B和C做右单旋,返回C
        return SingleL_Rotation(A); //!A和做左单旋,返回C
    }
    //!右左双旋:RL
    AVLTree DoubleRL_Rotation(AVLTree A)
    {
        A->right=SingleL_Rotation(A->right);
        return SingleR_Rotation(A);
    }
    
    //!将x插入AVL树T中,并且返回调整后的AVL树
    AVLTree AVL_Insertion(int x,AVLTree T)
    {
        if(!T)  //!若插入空树,则新建包含一个节点的树
        {
            T=new AVLTreeNode;
            T->data=x;
            T->height=0;
            T->left=T->right=NULL;
        }
        else if(x<T->data)  //!插入T的左子树
        {
            T->left=AVL_Insertion(x,T->left);
            if(GetHeight(T->left)-GetHeight(T->right)==2)
            {
                //!需左旋
                if(x<T->left->data)
                    T=SingleL_Rotation(T);  //!左单旋:LL
                else
                    T=DoubleLR_Rotation(T); //!左右双旋:LR
            }
        }
        else if(x>T->data)  //!插入T的右子树
        {
            T->right=AVL_Insertion(x,T->right);
            if(GetHeight(T->left)-GetHeight(T->right)==-2)
            {
                //!需右旋
                if(x>T->right->data)
                    T=SingleR_Rotation(T);  //!右单旋:RR
                else
                    T=DoubleRL_Rotation(T); //!右左双旋:RL
            }
        }
        else    //! x==T->data, 无需插入
            return T;
    
        //!更新树高
        T->height=Max(GetHeight(T->left),GetHeight(T->right))+1;
        return T;
    }
    
    int main()
    {
        int n,x;
        cin >> n;
        AVLTree root=NULL;
        for(int i=0;i<n;i++)
        {
            cin >> x;
            root=AVL_Insertion(x,root);
        }
        cout << root->data << endl;
        return 0;
    }
  • 相关阅读:
    LeetCode "Jump Game"
    LeetCode "Pow(x,n)"
    LeetCode "Reverse Linked List II"
    LeetCode "Unique Binary Search Trees II"
    LeetCode "Combination Sum II"
    LeetCode "Divide Two Integers"
    LeetCode "First Missing Positive"
    LeetCode "Clone Graph"
    LeetCode "Decode Ways"
    LeetCode "Combinations"
  • 原文地址:https://www.cnblogs.com/claremore/p/4809392.html
Copyright © 2011-2022 走看看