04-树5 Root of AVL Tree (25分)

04-树5 Root of AVL Tree (25分)

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.

 

 

 

 

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 (≤) 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

2020-07-22

提交代码:

#include <stdio.h>
#include <stdlib.h>

typedef int ElemType;
typedef struct AVLNode *Position;
typedef Position AVLTree;
struct AVLNode{
    ElemType Data;
    AVLTree Left;
    AVLTree Right;
    int Height;
};

int Max(int a, int b){
    return a > b ? a : b;
}

int GetHeight(AVLTree T){
    if(!T){
        return -1;
    }
    return T->Height;
}

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), GetHeight(B->Right)) + 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->Left), GetHeight(B->Right)) + 1;
    return B;
}

AVLTree DoubleLeftRotation( AVLTree A ){
    A->Left = SingleRightRotation(A->Left);
    return SingleLeftRotation(A);
}

AVLTree DoubleRightRotation( AVLTree A ){
    A->Right = SingleLeftRotation(A->Right);
    return SingleRightRotation(A);
}

AVLTree Insert( AVLTree T, ElemType X ){
    if(!T){
        T = (AVLTree)malloc(sizeof(struct AVLNode));
        T->Data = X;
        T->Height = 0;
        T->Left = NULL;
        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 = DoubleLeftRotation(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 = DoubleRightRotation(T);
            }
        }
    }
    T->Height = Max( GetHeight(T->Left), GetHeight(T->Right)) + 1;
    return T;
}

int main(){
    int N, X;
    AVLTree T = NULL;
    scanf("%d", &N);
    for(int i = 0; i < N; ++i){
        scanf("%d", &X);
        T = Insert(T, X);
    }
    printf("%d", T->Data);
    return 0;
}

提测结果:

2021-07-29 更新

以下代码能够提交通过测试,存在错误,错误原因在于:左左旋转或者右右旋转时,不更新树高;

题目中的第一个例子的测试却无法通过,神奇!

错误示例代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct AVLTree *Tree;
typedef int DataType;

struct AVLTree
{
    Tree left;
    Tree right;
    DataType data;
    int height;
};

DataType Abs(int x){
    if(x<0)
        return -x;
    return x;
}

int GetHeight(Tree root){
    if(!root){
        return -1;
    }
    return root->height;
}

Tree AVL_LL(Tree root){
    if(!root){
        return NULL;
    }
    Tree tmp = root->left;
    root->left = tmp->right;
    tmp->right = root;
    return tmp;
}

Tree AVL_RR(Tree root){
    if(!root){
        return NULL;
    }
    Tree tmp = root->right;
    root->right = tmp->left;
    tmp->left = root;
    return tmp;
}

Tree AVL_LR(Tree root){
    if(!root){
        return NULL;
    }
    root->left = AVL_RR(root->left);
    return AVL_LL(root);
}

Tree AVL_RL(Tree root){
    if(!root){
        return NULL;
    }
    root->right = AVL_LL(root->right);
    return AVL_RR(root);
}

Tree AVL_Rotate(Tree root){
    if(!root){
        return NULL;
    }
    if(GetHeight(root->left) > GetHeight(root->right)){
        if(GetHeight(root->left->left) > GetHeight(root->left->right)){
            root = AVL_LL(root);
        }
        else{
            root = AVL_LR(root);
        }
    }
    else{
        if(GetHeight(root->right->left) > GetHeight(root->right->right)){
            root = AVL_RL(root);
        }
        else{
            root = AVL_RR(root);
        }
    }
    return root;
}

//调整AVL树
Tree AVL_Adjust(Tree root){
    if(!root){
        return NULL;
    }
    if(Abs(GetHeight(root->left) - GetHeight(root->right)) == 2){
        root = AVL_Rotate(root);
    }
    
    if(GetHeight(root->left) >= GetHeight(root->right)){
        root->height = GetHeight(root->left) + 1;
    }
    else if(GetHeight(root->left) < GetHeight(root->right)){
        root->height = GetHeight(root->right) + 1;
    }
    return root;
}

Tree Insert(Tree root, int data){
    if(!root){
        root = (Tree)malloc(sizeof(struct AVLTree));
        root->data = data;
        root->left = NULL;
        root->right = NULL;
        root->height = 0;
        return root;
    }
    if(data > root->data){
        root->right = Insert(root->right, data);
    }
    else if(data < root->data){
        root->left = Insert(root->left, data);
    }
    root = AVL_Adjust(root);
    return root;
}

Tree MakeAVLTree(){
    int N = 0;
    scanf("%d", &N);
    Tree root = NULL;
    DataType data = -1;
    for(int i = 0; i < N; i++){
        scanf("%d",&data);
        root = Insert(root, data);
    }
    return root;
}

int main(){
    Tree root = MakeAVLTree();
    if(root){
        printf("%d", root->data);
    }
    else{
        printf("0");
    }
    return 0;
}
View Code

提交结果:

 

 正确代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct AVLTree *Tree;
typedef int DataType;

struct AVLTree
{
    Tree left;
    Tree right;
    DataType data;
    int height;
};

int Abs(int x){
    if(x < 0)
        return -x;
    return x;
}

int Max(int a, int b){
    return a > b ? a : b;
}

int GetHeight(Tree root){
    if(!root){
        return -1;
    }
    return root->height;
}

void UpdateHeight(Tree root){
    root->height = Max(GetHeight(root->left), GetHeight(root->right)) + 1;
}

Tree AVL_LL(Tree A){
    if(!A){
        return NULL;
    }
    Tree B = A->left;
    A->left = B->right;
    B->right = A;
    UpdateHeight(A);
    UpdateHeight(B);
    return B;
}

Tree AVL_RR(Tree A){
    if(!A){
        return NULL;
    }
    Tree B = A->right;
    A->right = B->left;
    B->left = A;
    UpdateHeight(A);
    UpdateHeight(B);
    return B;
}

Tree AVL_LR(Tree root){
    if(!root){
        return NULL;
    }
    root->left = AVL_RR(root->left);
    return AVL_LL(root);
}

Tree AVL_RL(Tree root){
    if(!root){
        return NULL;
    }
    root->right = AVL_LL(root->right);
    return AVL_RR(root);
}

Tree AVL_Rotate(Tree root){
    if(!root){
        return NULL;
    }
    if(GetHeight(root->left) > GetHeight(root->right)){
        if(GetHeight(root->left->left) > GetHeight(root->left->right)){
            root = AVL_LL(root);
        }
        else{
            root = AVL_LR(root);
        }
    }
    else{
        if(GetHeight(root->right->left) > GetHeight(root->right->right)){
            root = AVL_RL(root);
        }
        else{
            root = AVL_RR(root);
        }
    }
    return root;
}

//调整AVL树
Tree AVL_Adjust(Tree root){
    if(!root){
        return NULL;
    }
    if(Abs(GetHeight(root->left) - GetHeight(root->right)) >= 2){
        root = AVL_Rotate(root);
    }
    UpdateHeight(root);
    return root;
}

Tree Insert(Tree root, int data){
    if(!root){
        root = (Tree)malloc(sizeof(struct AVLTree));
        root->data = data;
        root->left = NULL;
        root->right = NULL;
        root->height = 0;
        return root;
    }
    if(data > root->data){
        root->right = Insert(root->right, data);
    }
    else if(data < root->data){
        root->left = Insert(root->left, data);
    }
    root = AVL_Adjust(root);
    return root;
}

Tree MakeAVLTree(){
    int N = 0;
    scanf("%d", &N);
    Tree root = NULL;
    DataType data = -1;
    for(int i = 0; i < N; i++){
        scanf("%d",&data);
        root = Insert(root, data);
    }
    return root;
}

int main(){
    Tree root = MakeAVLTree();
    if(root){
        printf("%d", root->data);
    }
    else{
        printf("0");
    }
    return 0;
}

 

posted @ 2020-07-22 00:49  余生以学  阅读(141)  评论(0编辑  收藏  举报