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\n", 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;
}
posted @ 2020-03-22 20:31  AndyHY  阅读(339)  评论(0编辑  收藏  举报