• 第五章 树 14 AcWing 1552. AVL树的根


    第五章 树 14 AcWing 1552. AVL树的根

    原题链接

    AcWing 1552. AVL树的根

    算法标签

    平衡树

    思路

    AVL树,即平衡二叉搜索树,当一棵二叉搜索树的左右子树高度相差(平衡因子)小于等于1时,我们称其为平衡二叉搜索树。
    当一棵二叉搜索树在插入数据时平衡被打破,我们需要手动调整树的节点使其重新满足平衡二叉搜索树的性质。

    平衡二叉树的基本操作

    平衡二叉搜索树有两种基本操作:左旋与右旋请添加图片描述

    右旋
    具体步骤

    使用临时变量保存根节点(即旋转节点)的左子树
    将根节点的左子树设置为左子树的右子树
    将保存的左子树的右子树设置为根节点。
    更新根节点以及该节点左子树的高度(注意顺序,由于此时根节点已经成为原左子树的右子树)。
    将根节点设置为临时保存的左子树

    代码
    void R(int &u){
        int p=l[u];
        l[u]=r[p],r[p]=u;
        update(u),update(p);
        u=p;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    左旋

    使用临时变量保存根节点(即旋转节点)右子树
    将根节点的右子树设置为右子树的左子树
    将保存的右子树的左子树设置为根节点。
    更新根节点以及该节点右子树的高度(注意顺序,由于此时根节点已经成为原先右子树的左子树)。
    将根节点设置为临时保存的右子树

    代码
    void R(int &u){
        int p=r[u];
        r[u]=l[p],l[p]=u;
        update(u),update(p);
        u=p;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    平衡二叉树的失衡情形以及对应解决方法

    使平衡二叉树失去平衡主要有四种情形:

    1. 左子树比右子树高2
    • 左子树的左子树比左子树的右子树高1(对应下图①)
    • 左子树的右子树比左子树的左子树高1(对应下图③)
    1. 右子树比左子树高2
    • 右子树的右子树比右子树的左子树高1(对应下图②)
    • 右子树的左子树比右子树的右子树高1(对应下图④)
      请添加图片描述
      解决方法为:
    • R(root)
    • L(l[root]), R(root)
    • L(root)
    • R(r[root]), L(root)

    这里的root指的是左右不平衡的节点(平衡因子大于2或小于-2)

    代码

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #include
    #define int long long
    #define x first
    #define y second
    #define ump unordered_map
    #define pq priority_queue
    #define rep(i, a, b) for(int i=a;i=b;--i)
    using namespace std;
    typedef pair PII;
    const int N = 10005;
    //int t, n, m, cnt, ans; 
    // l[i]存储节点i的左节点 r[i]存储节点i的左节点 v[i]存储节点i的权值 h[i]存储节点i的高度 idx存储当前已用到的节点个数
    int l[N], r[N], v[N], h[N], idx;
    inline int rd(){
       int s=0,w=1;
       char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
       while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
       return s*w;
    }
    void put(int x) {
        if(x<0) putchar('-'),x=-x;
        if(x>=10) put(x/10);
        putchar(x%10^48);
    }
    // 计算节点u高度 即左右节点最高高度+1
    void update(int u){
        h[u]=max(h[l[u]], h[r[u]])+1;
    }
    // 对于传入的u值 也需要改变
    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_l(int u){
        return h[l[u]]-h[r[u]];
    }
    // 子节点w插入根节点u中 
    void insert(int &u, int w){
        if(!u){
            u=++idx;
            v[u]=w;
        }else if(w
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    参考文献

    AcWing 1552. AVL树的根(PAT甲级辅导课)y总视频讲解
    AcWing 1552. AVL树详解

    原创不易
    转载请标明出处
    如果对你有所帮助 别忘啦点赞支持哈
    在这里插入图片描述

  • 相关阅读:
    JVM-环境准备&性能指标&基础知识
    【云原生持续交付和自动化测试】5.2 自动化测试和集成测试
    Rust学习笔记:深度解析内存管理(二)
    海思平台水印功能实现之二定时器Timer
    idea:JavaWeb(maven)Servlet 03
    Linux 连接工具
    _pickle.UnpicklingError: STACK_GLOBAL requires str
    P1-Python编辑器的选择和安装
    2023年Java毕业设计题目如何选题?Java毕业设计选题大全
    音频学习笔记之音频采集
  • 原文地址:https://blog.csdn.net/T_Y_F_/article/details/127814253