目录
1,题目描述
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
题目大意
给出一个序列,输出按照此序列构造的AVL树的根节点的值。
2,思路
题目意思很直接,就是赤裸裸地构造AVL树。
AVL树
平衡二叉树(Balance Binary Tree),又称AVL树,是一棵二叉排序树,或者为空,或者满足以下条件:
- 左、右子树高度差的绝对值不大于1;
- 左、右子树都是平衡二叉树。
平衡二叉树可以确保平均查找长度较小。
不平衡的类型
根据新插入结点与最低不平衡结点的位置关系分为LL型、RR型、LR型和RL型4种类型分别处理:
(注:A为最底不平衡点;方框表示子树;灰色方框为新插入的节点;节点的调整顺序很重要)
LL型
①B的右子树调为A的左子树,即:A->lChild=B->rChild;
② A调为B的右孩子,即:B->rChild=A;
③ B成为调整后的子树根结点。
RR型
① B的左子树调为A的右子树,即: A->rChild=B->lChild;
② A调为B的左孩子,即: B->lChild=A;
③ B成为调整后的子树根结点。
LR型
① C的左子树调为B的右子树,即:B->rChild=C->lChild;
C的右子树调为A的左子树,即:A->lChild=C->rChild;
② B调为C的左子树,即:C->lChild=B;
A调为C的右子树,即:C->rChild=A;
③ C成为调整后的子树根结点;
RL型
① C的左子树调为A的右子树,即:A->rChild=C->lChild;
C的右子树调为B的左子树,即:B->lChild=C->rChild;
② A调为C的左孩子,即:C->lChild=A;
B调为C的右孩子,即:C->rChild=B;
③ C成为调整后的子树根结点。
插入节点
设计函数:
int getHeight(node *root):获得当前节点的高度;
node *insert(node *root, int val):插入值为val的节点;
(递归过程的理解:在最低处的节点插入数据后,函数返回,检查节点的父节点平衡是否被破坏,若被破坏,则进行调整;将其父节点替换为当前节点,继续递归。。。)
int getHeight(node *root){
if(root == NULL) return 0;
return max(getHeight(root->left), getHeight(root->right)) + 1;
}
node *insert(node *root, int val){
if(root == NULL){
root = new node();
root->value = val;
root->left = root->right = NULL;
}
else if(val < root->value){
root->left = insert(root->left, val);
//插入节点后需要判断当前节点的平衡是否被破坏
if(getHeight(root->left) - getHeight(root->right) == 2){//root最低不平衡节点
root = val < root->left->value ? rotateLL(root) : rotateLR(root);
}
}
else{
root->right = insert(root->right, val);
if(getHeight(root->left) - getHeight(root->right) == -2){//root最低不平衡节点
root = val > root->right->value ? rotateRR(root) : rotateRL(root);
}
}
return root;//最终的根节点
}
3,AC代码
#include<bits/stdc++.h>
using namespace std;
struct node{
int value;
struct node *left, *right;
};
node *rotateLL(node *root){
node *t = root->left;
root->left = t->right;
t->right = root;
return t;
}
node *rotateRR(node *root){
node *t = root->right;
root->right = t->left;
t->left = root;
return t;
}
node *rotateLR(node *root){
node *A = root, *B = root->left, *C = root->left->right;
B->right = C->left;
A->left = C->right;
C->left = B;C->right = A;
return C;
}
node *rotateRL(node *root){
node *A = root, *B = root->right, *C = root->right->left;
A->right = C->left;
B->left = C->right;
C->left = A;C->right = B;
return C;
}
int getHeight(node *root){
if(root == NULL) return 0;
return max(getHeight(root->left), getHeight(root->right)) + 1;
}
node *insert(node *root, int val){
if(root == NULL){
root = new node();
root->value = val;
root->left = root->right = NULL;
}
else if(val < root->value){
root->left = insert(root->left, val);
if(getHeight(root->left) - getHeight(root->right) == 2){//root最低不平衡节点
//root = val < root->left->value ? rotateLL(root) : rotateLR(root);
if(val < root->left->value)
root = rotateLL(root);//LL型 需向右旋转
else
root = rotateLR(root);
}
}
else{
root->right = insert(root->right, val);
if(getHeight(root->left) - getHeight(root->right) == -2){//root最低不平衡节点
root = val > root->right->value ? rotateRR(root) : rotateRL(root);
}
}
return root;//最终的根节点
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
int N, val;
node *AVLTree = NULL;
scanf("%d", &N);
for(int i = 0; i < N; i++){
scanf("%d", &val);
AVLTree = insert(AVLTree, val);
}
printf("%d", AVLTree->value);
return 0;
}