Root of AVL Tree

 

17196671-18dc7f811dd74314.png

image.png


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

 

https://pintia.cn/problem-sets/1112649714742542336/problems/1112650627825745920
关于平衡二叉树:

  • 平衡因子(BF, balance factor): 左子树高度减去右子树高度.子树为空时高度为负一这种设定十分巧妙,惊叹于人类的智慧.
    当一棵二叉树所有节点的BF绝对值都不大于1时,这棵树被称为平衡二叉树(AVL Tree).
    然而,当某一二叉树不平衡时,该如何使其变为AVL Tree呢?
  • 从trouble finder 的三层节点进行调整
    (XX表示trouble maker在trouble finder的X子树的X子树上)
  1. RR:

     

    17196671-368ef9d365ddf6b4.png

    image.png

  2. LL:

     

    17196671-e4f915ba305e2630.png

    image.png

     

    前两种是较为简单的旋转.而后两种则是前两种的复合:

  3. LR:

     

    17196671-10ccd926859c77fc.png

    image.png

     

    可以看作先以B为根进行RR再以A为根进行LL

  4. PL:

     

    17196671-b1545edb2588bca2.png

    image.png

     

    可以看作先以B为根进行LL再以A为根进行RR

  • 最后直接贴代码吧
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct TreeNode{
    int key, height;
    TreeNode *left, *right;
    //第一反应是还要设*parent和*BF,由此可见对树结构的理解还很差啊 
};
typedef struct TreeNode *T;
typedef struct TreeNode *AvlTree;
AvlTree Insert(T t, int x);
AvlTree LL(T t);
AvlTree RR(T t);
AvlTree LR(T t);
AvlTree RL(T t);
//第一反应是将Insert和旋转函数设为void,但参考题解后惊叹于AvlTree 妙啊妙 
//由上可以看出我对递归的理解还是不够... 
int Height(T t);//个人认为最巧妙的函数之一 
int Max(int a, int b);
int main(){
    int n, x;
    AvlTree root = NULL;
    scanf("%d", &n);
    while(n--){
        scanf("%d", &x);
        root = Insert(root, x);
    }
    printf("%d", root -> key);
    return 0;
}
AvlTree LL(T t){
    T l = t -> left;
    t ->left = l -> right;
    l -> right = t;
    t -> height = Max(Height(t -> left), Height(t -> right)) + 1;
    l -> height = Max(Height(l -> left), Height(l -> right)) + 1;
    return l;
}
AvlTree RR(T t){
    T r = t -> right;
    t -> right = r -> left;
    r -> left = t;
    t -> height = Max(Height(t -> left), Height(t -> right)) + 1;
    r -> height = Max(Height(r -> left), Height(r -> right)) + 1;
    return r;
}
AvlTree LR(T t){
    t -> left = RR(t -> left);
    return LL(t);
}
AvlTree RL(T t){
    t -> right = LL(t -> right);
    return RR(t);
}
AvlTree Insert(T t, int x){
    if(t == NULL){
        t = (T)malloc(sizeof(T));
        t -> key = x;
        t -> left = t -> right = NULL;
        t -> height = 0;
    }
    else{
        if(x < t -> key){
            t -> left = Insert(t -> left, x);
            if(Height(t -> left) - Height(t -> right) == 2){
                if(x < t -> left -> key) t = LL(t); //LL
                else t = LR(t);//LR 
            }
        }
        else{
            t -> right = Insert(t -> right, x);
            if(Height(t -> right) - Height(t -> left) == 2){
                if(x < t -> right ->key) t = RL(t); //RL
                else t = RR(t);//RR
            }
        }
    }
    t -> height = Max(Height(t -> left), Height(t -> right)) + 1;
    return t;
}
int Height(T t){ 
    if(t == NULL) return -1;
    return t -> height;
}
int Max(int a, int b){
    return (a > b) ? a : b;
}

参考题解www.cnblogs.com/llhthinker/p/4770099.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值