为什么需要AVL树
二叉搜索树的搜索效率与其树的深度相关,而二叉搜索树的组成又与其插入序列相关,在极端情况下,二叉搜索树退化为一条单链(比如插入序列是 1 2 3 … n),使得搜索效率大大降低,为了避免这种情况出现,我们采用二叉平衡树对插入结点进行调整,使得树的深度尽可能小
定义
-
平衡因子
BF(T)=hL-hR
hL和hR分别为左子树和右子树的高度 -
平衡二叉树
左右子树高度之差不超过1,即|Bf(t)|<=1
AVL树四大调整
1. LL单旋
即要插入的节点为根节点的左子树的左子树,
把b的右节点作为A的左节点
把b换位根节点,
node * LLrotation(node * root){
node * temp=root->left;
root->left=temp->right;
temp->right=root;
return temp;
}
2. RR单旋
道理同上,把B的左子树作为A的右子树,把B作为根节点
node * RRrotation(node *root){
node *temp=root->right;
root->right=temp->left;
temp->left=root;
return temp;
}
3. LR双旋
要插入的节点为根节点的左子树的右子树,
先进性RR单旋,把C换为B的父节点,A作为C的父节点,
再进行LL单旋,把C作为A的父节点,C成为根节点
node *LRrotation(node *root){
root->left=RRrotation(root->left);
return LLrotation(root);
}
4. RL双旋
道理相同
node *RLrotation(node *root){
root->right=LLrotation(root->right);
return RRrotation(root);
}
练习
#include<bits/stdc++.h>
using namespace std;
struct node{
node * left;
node * right;
int height;
int data;
};
int getHeight(node *root){
return root==NULL?0:root->height;
}
node * RRrotation(node *root){
node *temp=root->right;
root->right=temp->left;
temp->left=root;
//跟新高度
root->height=max(getHeight(root->left),getHeight(root->right))+1;
temp->height=max(root->height,getHeight(temp->right))+1;
return temp;
}
node * LLrotation(node * root){
node * temp=root->left;
root->left=temp->right;
temp->right=root;
root->height=max(getHeight(root->left),getHeight(root->right))+1;
temp->height=max(root->height,getHeight(temp->left))+1;
return temp;
}
node *LRrotation(node *root){
root->left=RRrotation(root->left);
return LLrotation(root);
}
node *RLrotation(node *root){
root->right=LLrotation(root->right);
return RRrotation(root);
}
node * insert(node *root,int data){
if(!root){
root=new node;
root->data=data;
root->left=NULL;
root->right=NULL;
root->height=0;
}else{
if(data<root->data){
root->left=insert(root->left,data);
if(getHeight(root->left)-getHeight(root->right)==2){
if(data<root->left->data){
root=LLrotation(root);
}else if(data>root->left->data){
root=LRrotation(root);
}
}
}else {
root->right=insert(root->right,data);
if(getHeight(root->right)-getHeight(root->left)==2){
if(data>root->right->data){
root=RRrotation(root);
}else if(data<root->right->data){
root=RLrotation(root);
}
}
}
}
//更新树高
root->height=max(getHeight(root->left),getHeight(root->right))+1;
return root;
}
int main(){
node *root=NULL;
int n;
cin>>n;
for(int i=0;i<n;i++){
int temp;
cin>>temp;
root=insert(root,temp);
}
cout<<root->data;
}