AVL 树是带平衡条件的的二叉查找树。
这里所指的平衡条件是:每个结点的左子树和右子树的高度最多差1,空树的高度定义为-1
对一颗AVL树进行插入操作的时候,极大可能会破坏树的平衡,此时需要对结点进行调整,以满足AVL 树的平衡条件。
而不平衡的情况有以下4种:
(1)对t 的左儿子的左子树进行一次插入
(2)对t的左儿子的右子树进行一次插入
(3)对t的右儿子的左子树进行一次插入
(4)对t的右儿子的右子树进行一次插入
其中(1)、(4)所作的调整为单旋转,(2)、(3)所作的调整为双旋转(双旋转由2次单旋转构成)。
AVL树的结点声明
struct AvlNode
{
int element;
AvlNode *left;
AvlNode *right;
int height;
AvlNode ( int e, AvlNode *l, AvlNode *r, int h )
: element ( e ), left ( l ), right ( r ), height ( h ) {}
};
AVL树的类:
public部分
class AvlTree
{
public:
AvlTree()
{
root = NULL;
}
AvlTree ( const AvlTree &rhs )
{
root = clone ( rhs.root );
}
const AvlTree & operator= ( const AvlTree &rhs )
{
if ( this != &rhs )
{
makeEmpty();
root = clone ( rhs.root );
}
return *this;
}
~AvlTree()
{
makeEmpty();
}
int height() const
{
return height ( root );
}
void insert ( int x )
{
insert ( x, root );
}
void makeEmpty()
{
makeEmpty ( root );
}
private部分
private:
AvlNode *root;
int height ( AvlNode *t ) const
{
return t == NULL ? -1 : t->height;
}
void insert ( int x, AvlNode *&t )
{
if ( t == NULL )
t = new AvlNode ( x, NULL, NULL, 0 );
else if ( x < t->element )
{
insert ( x, t->left );
if ( height ( t->left ) - height ( t->right ) == 2 )
if ( x < t->left->element )
rotateWithLeftChild ( t ); //左单旋转
else
doubleWithLeftChild ( t ); //左双旋转
}
else if ( t->element < x )
{
insert ( x, t->right );
if ( height ( t->right ) - height ( t->left ) == 2 )
if ( t->right->element < x )
rotateWithRightChild ( t ); //右单旋转
else
doubleWithRightChild ( t ); //右双旋转
}
else
;
t->height = max ( height ( t->left ), height ( t->right ) ) + 1;
}
void rotateWithLeftChild ( AvlNode *&t )
{
AvlNode *k = t->left;
t->left = k->right;
k->right = t;
t->height = max ( height ( t->left ), height ( t->right ) ) + 1;
k->height = max ( height ( k->left ), t->height ) + 1;
t = k;
}
void rotateWithRightChild ( AvlNode *&t )
{
AvlNode *k = t->right;
t->right = k->left;
k->left = t;
t->height = max ( height ( t->left ), height ( t->right ) ) + 1;
k->height = max ( t->height, height ( k->right ) ) + 1;
t = k;
}
void doubleWithLeftChild ( AvlNode *&t )
{
rotateWithRightChild ( t->left );
rotateWithLeftChild ( t );
}
void doubleWithRightChild ( AvlNode *&t )
{
rotateWithLeftChild ( t->right );
rotateWithRightChild ( t );
}
void makeEmpty ( AvlNode *&t )
{
if ( t != NULL )
{
makeEmpty ( t->left );
makeEmpty ( t->right );
delete t;
}
t = NULL;
}
AvlNode *clone ( AvlNode *t ) const
{
if ( t == NULL )
return NULL;
return new AvlNode ( t->element, clone ( t->left ), clone ( t->right ), t->height );
}
};
对于AVL 树的查找、删除、遍历输出等操作的代码可参考二叉查找树类模板的实现。(AVL树本身就是一个二叉查找树)