一、AVL构造思路
1、定义
(1)平衡因子:结点的平衡因子为其左子树的高度减去右子树的高度。
(2)AVL树:AVL树是所有结点平衡因子绝对值不超过1的BST(二叉查找树)。
因此首先定义AVL树的数据结构:
struct node
{
int data, h;
node *lchild, *rchild;
};
node *root = NULL;
2、平衡
·平衡对象:最小失衡子树,也就是以自下而上第一个平衡因子绝对值大于一的结点为根的子树;
(1)在最小失衡结点,左子树的左子树插入导致失衡:对最小失衡子树做右旋;
右旋操作:
void R( node *&t )
{
node *temp = t->lchild;
t->lchild = temp->rchild;
temp->rchild = t;
update(t);
t = temp;
}
(2) 在最小失衡结点,右子树的右子树插入导致失衡:对最小失衡子树做左旋;
左旋操作参考右旋。
void L( node *&t )
{
node *temp = t->rchild;
t->rchild = temp->lchild;
temp->lchild = t;
update(t);
t = temp;
}
(3)在最小失衡结点,左子树的右子树插入导致失衡:对最小失衡子树左子树做左旋,再对最小失衡子树右旋;
(4)在最小失衡结点,右子树的左子树插入导致失衡:对最小失衡子树右子树做右旋,再对最小失衡子树左旋;
先右后左旋转操作:
完整的插入函数:
void insert( node *&t, int key )
{
if( !t )
{
t = new node;
t->data = key;
t->lchild = t->rchild = NULL;
t->h = 1;
}
else if( key < t->data )
{
insert( t->lchild, key );
if( factor(t) == 2 && factor(t->lchild) == 1 )
R(t);
else if( factor(t) == 2 && factor(t->lchild) == -1 )
{
L(t->lchild);
R(t);
}
update(t);
}
else
{
insert( t->rchild, key );
if( factor(t) == -2 && factor(t->rchild) == -1 )
L(t);
else if( factor(t) == -2 && factor(t->rchild) == 1 )
{
R(t->rchild);
L(t);
}
update(t);
}
}
二、代码
#include <cstdio>
#include <algorithm>
using namespace std;
struct node
{
int data, h;
node *lchild, *rchild;
};
int get_h( node *t )
{
return t ? t->h:0;
}
int factor( node *t )
{
return get_h(t->lchild) - get_h(t->rchild);
}
void update( node *&t )
{
t->h = max( get_h(t->lchild), get_h(t->rchild) ) + 1;
}
void R( node *&t )
{
node *temp = t->lchild;
t->lchild = temp->rchild;
temp->rchild = t;
update(t);
t = temp;
}
void L( node *&t )
{
node *temp = t->rchild;
t->rchild = temp->lchild;
temp->lchild = t;
update(t);
t = temp;
}
void insert( node *&t, int key )
{
if( !t )
{
t = new node;
t->data = key;
t->lchild = t->rchild = NULL;
t->h = 1;
}
else if( key < t->data )
{
insert( t->lchild, key );
if( factor(t) == 2 && factor(t->lchild) == 1 )
R(t);
else if( factor(t) == 2 && factor(t->lchild) == -1 )
{
L(t->lchild);
R(t);
}
update(t);
}
else
{
insert( t->rchild, key );
if( factor(t) == -2 && factor(t->rchild) == -1 )
L(t);
else if( factor(t) == -2 && factor(t->rchild) == 1 )
{
R(t->rchild);
L(t);
}
update(t);
}
}
int main()
{
int N;
node *root = NULL;
scanf("%d", &N);
for( int i = 0, key; i < N; ++i )
{
scanf("%d", &key);
insert(root, key);
}
printf("%d", root->data);
}