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子树上)
-
RR:
image.png
-
LL:
image.png
前两种是较为简单的旋转.而后两种则是前两种的复合:
-
LR:
image.png
可以看作先以B为根进行RR再以A为根进行LL
-
PL:
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;
}