【PAT甲级 - C++题解】1066 Root of AVL Tree

简介: 【PAT甲级 - C++题解】1066 Root of AVL Tree

1066 Root of 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.



57bad82fbac84248874fc52dfe16f7bb.jpg



e395f0cf48404f95b76679a3c1c2ae0a.jpg


0aea6f3a0dbf48c98d4a0fff0f0b389f.jpg



94cdf997a73242188b92fc6074007380.jpg


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
• 1
• 2

Sample Output 1:

70



Sample Input 2:

7
88 70 61 96 120 90 65
• 1
• 2

Sample Output 2:

88


题意

给定一个序列,让我们构建起一颗 AVL 树,并输出它的根结点。


思路

平衡二叉树失衡主要分为四种情况,下面讨论的是导致失衡前最后插入的一个结点位置:


插入的结点在失衡结点的左孩子的左子树,直接右旋失衡结点。

插入的结点在失衡结点的左孩子的右子树,先对失衡结点的左孩子进行左旋,再对失衡结点右旋。

插入的结点在失衡结点的右孩子的右子树,直接左旋失衡结点。

插入的结点在失衡结点的右孩子的左子树,先对失衡结点的右孩子进行右旋,再对失衡结点左旋。

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 25;
int l[N], r[N], v[N], h[N], idx;
int n;
//更新当前结点的深度
void update(int u)
{
    h[u] = max(h[l[u]], h[r[u]]) + 1;
}
//右旋
void R(int& u)
{
    int p = l[u];
    l[u] = r[p], r[p] = u;
    update(u), update(p);
    u = p;
}
//左旋
void L(int& u)
{
    int p = r[u];
    r[u] = l[p], l[p] = u;
    update(u), update(p);
    u = p;
}
//获取左右结点深度之差
int get_balance(int u)
{
    return h[l[u]] - h[r[u]];
}
//插入结点
void insert(int& u, int w)
{
    if (!u)  u = ++idx, v[u] = w;
    else if (w < v[u])
    {
        insert(l[u], w);
        if (get_balance(u) == 2)
        {
            //如果插入结点在失衡结点的左孩子的左子树,则对失衡结点右旋
            if (get_balance(l[u]) == 1)   R(u);
            //如果插入结点在失衡结点的左孩子的右子树,则先对左孩子左旋,再对失衡结点右旋
            else    L(l[u]), R(u);
        }
    }
    else
    {
        insert(r[u], w);
        if (get_balance(u) == -2)
        {
            //如果插入结点在失衡结点的右孩子的右子树,则对失衡结点左旋
            if (get_balance(r[u]) == -1)   L(u);
            //如果插入结点在失衡结点的右孩子的左子树,则先对右孩子右旋,再对失衡结点左旋
            else    R(r[u]), L(u);
        }
    }
    update(u);  //更新当前结点的深度
}
int main()
{
    cin >> n;
    int root = 0;
    for (int i = 0; i < n; i++)
    {
        int w;
        cin >> w;
        insert(root, w);
    }
    cout << v[root] << endl;
    return 0;
}


目录
相关文章
|
6月前
|
C++
【数据结构】—AVL树(C++实现)
【数据结构】—AVL树(C++实现)
|
6月前
|
算法 测试技术 C++
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(下)
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(下)
|
6月前
|
C++ 容器
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(上)
【C++】map&set的底层结构 -- AVL树(高度平衡二叉搜索树)(上)
|
2月前
|
存储 C++
【C++】AVL树
AVL树是一种自平衡二叉搜索树:它以苏联科学家Georgy Adelson-Velsky和Evgenii Landis的名字命名。
27 2
|
6月前
|
存储 C++ 容器
c++的学习之路:26、AVL树
c++的学习之路:26、AVL树
49 0
|
3月前
|
C++ 容器
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——AVL树
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——AVL树
32 5
|
4月前
|
C++
【C++】手撕AVL树(下)
【C++】手撕AVL树(下)
51 1
|
4月前
|
算法 测试技术 C++
【C++高阶】掌握AVL树:构建与维护平衡二叉搜索树的艺术
【C++高阶】掌握AVL树:构建与维护平衡二叉搜索树的艺术
35 2
|
4月前
|
Java C++ Python
【C++】手撕AVL树(上)
【C++】手撕AVL树(上)
52 0
|
6月前
|
C语言 容器
从C语言到C++_27(AVL树)概念+插入接口实现(四种旋转)(上)
从C语言到C++_27(AVL树)概念+插入接口实现(四种旋转)
47 4