定义:AVL树是最先发明的自平衡二叉检索树
性质:性质大部分与普通的BST树相同,但是AVL树还增加了一个性质:对于每一个节点,要么没有子节点,要么左右子树高度差的绝对值不超过1,
插入和删除操作:
AVL树的其他操作与正常的BST树 没有什么不同,但是由于AVL树必须要保持左右子树高度差的绝对值不超过1的性质,故AVL树的插入和删除操作相对于普通的BST树而言,增加的调整高度的操作
插入
在AVL树中插入一个节点,可能会破坏AVL树的性质,具体有以下情况
LL,左子树中的左孩子插入节点导致不平衡,进行右旋
RR ,右子树的右孩子插入节点导致不平衡,进行左旋
LR,左子树的右孩子插入节点导致不平衡,先做对左子节点进行左旋形成一条直线,在对该点进行右旋
RL,右子树的左孩子插入节点导致不平很,先对右子节点进行右旋形成一条直线,再对该点进行左旋![](https://img-blog.csdnimg.cn/20190408215508810.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1MzQzNTU3,size_16,color_FFFFFF,t_70)
代码实现
private:
Node* leftRotate(Node*y)
{
Node*x=y->right();
Node*temp=x->left();
x->setLeft(y);
y->setRight(temp);
x->height=1+max(getHeight(x->right())
,getHeight(x->left()));
y->height=1+max(getHeight(y->right())
,getHeight(y->left()));
return x;
}
Node* rightRotate(Node*y)
{
Node*x=y->left();
Node*temp=x->right();
x->setRight(y);
y->setLeft(temp);
x->height=1+max(getHeight(x->left()),
getHeight(x->right()));
y->height=1+max(getHeight(y->right())
,getHeight(y->left()));
return x;
}
Node*inserthelp(Node*root,int num)
{
if(root==NULL)
{
++size;
return new Node(num);
}
else if(root->getValue()>num)
root->setLeft(inserthelp(root->left(),num));
else
root->setRight(inserthelp(root->right(),num));
//printf("正在插数%d\n",root->getValue());
root->height=1+max(getHeight(root->left())
,getHeight(root->right()));
int Balanced=getBalanceFactor(root);
if(Balanced>1&&getBalanceFactor(root->right())>0)
root=leftRotate(root);//左旋
else if(Balanced<-1&&getBalanceFactor(root->left())<0)
root=rightRotate(root);
else if(Balanced>1&&getBalanceFactor(root->right())<0)
{
root->setRight(rightRotate(root->right()));
root=leftRotate(root);
}
else if(Balanced<-1&&getBalanceFactor(root->left())>0)
{
root->setLeft(leftRotate(root->left()));
root=rightRotate(root);
}
return root;
}
public:
void insert(int num)
{
root=inserthelp(root,num);
}
注:上述代码中出现的函数的介绍如下:
getValue()得到某一点的值,getHeight()返回某一点的高度,getBalanceFactor()返回平衡因子(右子树的高度-左子树的高度)
删除
删除操作与BST树的删除相似,但是也增加了调整高度的操作,具体思想跟插入相似,这里就不详细介绍了
Node*removehelp(Node*root,int num)
{
if(root==NULL)return NULL;
else if(num<root->getValue())
root->setLeft(removehelp(root->left(),num));
else if(num>root->getValue())
root->setRight(removehelp(root->right(),num));
else
{
Node*temp;
if(root->left()==NULL)
temp=root->right();
else if(root->right()==NULL)
temp=root->left();
else
{
temp=getmin(root->right());
temp->setRight(delemin(root->right()));
temp->setLeft(root->left());//进行了插入的操作
}
delete root;//可以删除节点了
if(temp==NULL)return NULL;//相当于没有了
temp->height=1+max(getHeight(temp->left()),
getHeight(temp->right()));
int Balanced=getBalanceFactor(temp);
if(Balanced>1&&getBalanceFactor(temp->right())>0)
temp=leftRotate(temp);
else if(Balanced<-1&&getBalanceFactor(temp->left())<0)
temp=rightRotate(temp);
else if(Balanced>1&&getBalanceFactor(temp->right())<0)
{
temp->setRight(rightRotate(temp->right()));
temp=leftRotate(temp);
}
else if(Balanced<-1&&getBalanceFactor(temp->left())>0)
{
temp->setLeft(leftRotate(temp->left()));
temp=rightRotate(temp);//右转
}
return temp;
}
}
注:上述函数的功能介绍
getmin(Node*root)得到以root为根的树中的值最小的节点
delemin(Node*root)删除以root为根的树中的值最小的节点