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;
    }
  • 相关阅读:
    C#读写xml文件
    实现SQL_SERVER的双机实时备份
    Microsoft .NET Pet Shop 4 架构与技术分析
    xp系统运行asp.net时候出现“服务器应用程序不可用”的必杀
    获取服务器根域名
    C#如何创建Xml文件
    用C#创建XML[简单代码]
    关闭Viewstate
    数字签名
    IE插件
  • 原文地址:https://www.cnblogs.com/claremore/p/4809392.html
Copyright © 2011-2022 走看看