04-树5 Root of AVL Tree

Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.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平衡树的实现,如果不懂原理,建议去看MOOC的视频,讲得非常清楚

代码(C++实现)

/* 04-树5 Root of AVL Tree */
/* Asunne */
/* 2022/12/18 */
#include <bits/stdc++.h>
using namespace std;
typedef int ElementType;
typedef struct AVLNode *AVLTree;
struct AVLNode
{
    ElementType data;
    AVLTree left;
    AVLTree right;
    int height;
};
/* 模块定义 */
AVLTree Tree_Insert(AVLTree Tree, ElementType data);
int Max(int a, int b);
int getHeight(AVLTree Tree);
AVLTree AVL_LLRotation(AVLTree A);
AVLTree AVL_RRRotation(AVLTree A);
AVLTree AVL_LRRotation(AVLTree A);
AVLTree AVL_RLRotation(AVLTree A);
/* LL旋转,先将B的右子树挂在A的左子树上,然后再将A挂在B的右子树上,最后返回根节点 */
AVLTree AVL_LLRotation(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;
}
/* RR旋转,先将B的左子树挂在A的右子树上,然后再将A挂在B的左子树上,最后返回根节点 */
AVLTree AVL_RRRotation(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->right), A->height) + 1;
    return B;
}
/* LR旋转,先将A的左子树进行一次RR旋转,然后再以A为根节点做一次LL旋转 */
AVLTree AVL_LRRotation(AVLTree A)
{
    A->left = AVL_RRRotation(A->left);
    A = AVL_LLRotation(A);
    return A;
}
/* RL旋转,先将A的右子树进行一次LL旋转,然后再以A为根节点做一次RR旋转 */
AVLTree AVL_RLRotation(AVLTree A)
{
    A->right = AVL_LLRotation(A->right);
    A = AVL_RRRotation(A);
    return A;
}
/* 获取树的高度 */
int getHeight(AVLTree Tree)
{
    /* 树高从0开始,不是从1开始,只有根节点的树高为0 */
    return Tree == NULL ? -1 : Tree->height;
}
/* 取最大值 */
int Max(int a, int b)
{
    return a > b ? a : b;
}
AVLTree Tree_Insert(AVLTree Tree, ElementType data)
{
    if (Tree == NULL)
    {
        /* 空树,则创建树 */
        Tree = (AVLTree)malloc(sizeof(struct AVLNode));
        Tree->data = data;
        Tree->left = NULL;
        Tree->right = NULL;
        Tree->height = 0;
    }
    else
    {
        if (data < Tree->data)
        {
            Tree->left = Tree_Insert(Tree->left, data); // 向左子树插入
            /* 判断是否失衡 */
            if (getHeight(Tree->left) - getHeight(Tree->right) == 2)
            {
                /* 如果失衡,判断是要进行LL还是LR旋转 */
                if (data < Tree->left->data)
                    Tree = AVL_LLRotation(Tree);
                else if (data > Tree->left->data)
                    Tree = AVL_LRRotation(Tree);
            }
        }
        else if (data > Tree->data)
        {
            Tree->right = Tree_Insert(Tree->right, data);
            /* 判断是否失衡 */
            if (getHeight(Tree->right) - getHeight(Tree->left) == 2)
            {
                /* 如果失衡,判断是要进行RR旋转还是RL旋转 */
                if (data > Tree->right->data)
                    Tree = AVL_RRRotation(Tree);
                else if (data < Tree->right->data)
                    Tree = AVL_RLRotation(Tree);
            }
        }
    }
    /* 每插入一个结点之后,都要更新相应的数高 */
    Tree->height = Max(getHeight(Tree->left), getHeight(Tree->right)) + 1;
    return Tree;
}
int main()
{
    int N; // 记录结点数
    cin >> N;
    AVLTree Tree = NULL;
    int data;
    for (int i = 0; i < N; i++)
    {
        cin >> data;
        Tree = Tree_Insert(Tree, data);
    }
    cout << Tree->data << endl;
    return 0;
}

参考博客:

链接 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值