1066 Root of AVL Tree

题目描述
知识点: 二叉搜索树,AVL树
思路: 本题就是一个构建AVL树的模板题,现模板如下:

  1. l,r数组表示某个节点的左右孩子。v用于存放节点值。h用于存放每个节点的高度
  2. 两种旋转操作实现:
void L(int &u){//左旋
    int p = r[u];
    r[u] = l[p];
    l[p] = u;
    u = p;
}

void R(int &u){//右旋
    int p = l[u];
    l[u] = r[p];
    r[p] = u;
    u = p;
}

对于左旋,就是先把根的左子树记录下来。然后左子树的根作为根,它的右子树连接到根上。原先的根左子树连接左子树的右子树。…十分绕,看图。右旋就是反过来,看图就好了。
> 在这里插入图片描述

  1. 四种情况的旋转:
    (1)LL型:对根节点右旋 (2)RR型:对根节点左旋 (3)LR型:首先对左子树的根左旋然后对根节点右旋 (4)RL型:首先对右子树的根右旋然后对根节点左旋

对于如何判断插入类型: 如果是某个节点失衡,即它的左子树高了。则判断它的左子树,若它的左子树的左子树比右子树高度小1,则是LR型,若>1则是LL型,不可能相等。因为已经失衡。

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 50;
int l[N],r[N],v[N],h[N],idx,n;
void R(int &u){//右旋
    int p = l[u];
    l[u] = r[p];
    r[p] = u;
    u = p;
}
void L(int &u){//左旋
    int p = r[u];
    r[u] = l[p];
    l[p] = u;
    u = p;
}
int update(int u){//更新树的高度
    if(u == 0) return 0;
    else h[u] = max(update(l[u]),update(r[u]))+1;
    return h[u];
}
int get_balance(int u){//求某个节点的左右子树高度之差
    return h[l[u]] - h[r[u]];
}
void insert(int &u,int x){
    if(!u){
        u = ++idx;
        v[u] = x;  
    }else{
        if(v[u] > x){//插入左边
            insert(l[u],x);         
            if(get_balance(u) >= 2){//发生了不平衡
                if(get_balance(l[u]) >= 1) //LL型
                   R(u);
                else{
                    L(l[u]);
                    R(u);
                }
            }
        }else{//插入右边
            insert(r[u],x);           
            if(get_balance(u) <= -2){
                if(get_balance(r[u]) <= -1) //RR型
                    L(u);
                else{
                    R(r[u]);
                    L(u);
                }
            }
        }        
    }
    update(u); 
}
int main(){
    cin>>n;
    int root = 0;
    while(n--){
        int v;
        cin>>v;
        insert(root,v);
    }
    cout<<v[root];
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值