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

    解题思路

    直接读取输入序列,一个一个地插入AVL树,最后打印出根结点的值即可。关键在于处理好左单旋、右单旋、左右双旋、右左双旋,其中后两个可以由前两个实现。另外,为了判断是否平衡,需要在结点中添加一个高度字段。

    代码

    #include <stdio.h>
    #include <stdlib.h>
    
    struct AVLNode {
        int data;
        int height;
        struct AVLNode *left;
        struct AVLNode *right;
    };
    typedef struct AVLNode *AVLTree;
    
    AVLTree insert(AVLTree root, int data);
    AVLTree singleLeftRotation(AVLTree a);
    AVLTree singleRightRotation(AVLTree a);
    AVLTree doubleLeftRightRotation(AVLTree a);
    AVLTree doubleRightLeftRotation(AVLTree a);
    int getHeight(AVLTree root);
    int max(int lhs, int rhs);
    
    int main() {
        AVLTree root = NULL;
        int N, data;
        scanf("%d", &N);
        for (int i = 0; i < N; i++) {
            scanf("%d", &data);
            root = insert(root, data);
        }
        if (root) printf("%d
    ", root->data);
        return 0;
    }
    
    AVLTree insert(AVLTree root, int data) {
        if (!root) {
            root = (AVLTree) malloc(sizeof(struct AVLNode));
            root->data = data; root->height = 0;
            root->left = NULL; root->right = NULL;
        } else if (data < root->data) {
            root->left = insert(root->left, data);
            if (getHeight(root->left) - getHeight(root->right) == 2) {
                if (data < root->left->data) {
                    root = singleLeftRotation(root);
                } else if (data > root->left->data) {
                    root = doubleLeftRightRotation(root);
                }
            }
        } else if (data > root->data) {
            root->right = insert(root->right, data);
            if (getHeight(root->left) - getHeight(root->right) == -2) {
                if (data < root->right->data) {
                    root = doubleRightLeftRotation(root);
                } else if (data > root->right->data) {
                    root = singleRightRotation(root);
                }
            }
        }
        root->height = max(getHeight(root->left), getHeight(root->right)) + 1;
        return root;
    }
    
    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(a->height, getHeight(b->right)) + 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);
    }
    
    int getHeight(AVLTree root) {
        if (!root) return -1;
        else return root->height;
    }
    
    int max(int lhs, int rhs) {
        return lhs > rhs ? lhs : rhs;
    }
    
  • 相关阅读:
    SVN的安装与配置
    nginx之location配置详解及案例
    查看三种MySQL字符集的方法(转)
    JAVA_OPTS设置
    vi/vim 添加或删除多行注释
    Linux 下查看字体
    linux 安装中文字体
    Linux 压缩某个文件夹命令
    Navicat Premium 12.1.16.0安装与激活
    Rsync + sersync 实时同步备份
  • 原文地址:https://www.cnblogs.com/AndyHY-Notes/p/12548098.html
Copyright © 2020-2023  润新知