AVL树即平衡二叉树,定义BF(Balanced Factor)=H(L)-H(R),其中BF为平衡因子,H(L)表示某一节点的左子树的总高度,H(R)表示节点的右子树的高度,当树的所有节点的平衡因子BF的绝对值小于等于1时,认为该树是一棵平衡二叉树。平衡二叉树存储结构的实现是在二叉搜索树的基础上增加平衡的限制,即当往树中插入节点或删除节点时,均需考虑变化后的树是否还是平衡二叉树,在此过程中涉及到平衡的判断、树结构的调整等内容。当插入节点时,首先按照二叉搜索书的插入方法进行,采用递归的方法而不是迭代,能否简化父节点左右儿子指针变化引起的复杂内容,只需通过返回插入节点指针给父节点的左右儿子指针值即可,若是新节点就动态分配一块内存并传递给父节点的儿子指针,若不是新节点就返回当前指针给父节点保持不变。每次递归插入后都需要判断该节点是否满足平衡条件,若不满足根据插入数据节点的相对位置进行4类调整:RR、LL、RL、LR。同时不要忘记每次都要更新该节点的高度,高度成员变量也是平衡二叉树单独引入的,便于判断平衡是否满足。删除节点与二叉搜索树类似,根据删除节点的度大小分为3种情况,这里不再具体说明。对于度为2的节点,平衡二叉树和二叉搜索树的区别在于平衡二叉树需要判断该节点的左右子树的高度,选择高的一个子树并从其中找最接近该节点值的节点进行替换。替换之后需要更新树节点的高度,并判断是否满足平衡条件,若不满足则根据左右子树及左右孙子树的高度判断需要利用那种旋转调整使其达到平衡。下面是AVL树存储结构的C++模板类实现源代码:
//AVLTree.h
#ifndef AVLTREE_H
#define AVLTREE_H
#include <IOSTREAM>
int MAX(int a,int b)
{
return a>b?a:b;
}
template<class Type>
struct AVLNode
{
Type data;
int height;
AVLNode<Type>* left;
AVLNode<Type>* right;
};
template<class Type>
class AVLTree
{
private:
AVLNode<Type>* root;
int* aa;
public:
AVLTree(){root=NULL;}
~AVLTree();
void ReleaseAVLNode(AVLNode<Type>*);
int GetHeight(AVLNode<Type>*);
void Insert(Type x);
void Remove(Type x);
AVLNode<Type>* Remove(AVLNode<Type>*&,Type);
AVLNode<Type>* Insert(AVLNode<Type>* &,Type);
AVLNode<Type>* LeftLeftRotation(AVLNode<Type>*);
AVLNode<Type>* RightRightRotation(AVLNode<Type>*);
AVLNode<Type>* LeftRightRotation(AVLNode<Type>*);
AVLNode<Type>* RightLeftRotation(AVLNode<Type>*);
void PreOrderTraversal(AVLNode<Type>*);
void PreOrderTraversal();
AVLNode<Type>* FindMax(AVLNode<Type>* );
AVLNode<Type>* FindMin(AVLNode<Type>* );
};
template<class Type>
AVLTree<Type>::~AVLTree()
{
ReleaseAVLNode(root);
}
template<class Type>
void AVLTree<Type>::ReleaseAVLNode(AVLNode<Type>* temp)
{
if(temp)
{
ReleaseAVLNode(temp->left);
ReleaseAVLNode(temp->right);
delete temp;
}
return;
}
template<class Type>
int AVLTree<Type>::GetHeight(AVLNode<Type>* temp)
{
if(!temp)
return 0;
return temp->height;
}
template<class Type>
void AVLTree<Type>::Insert(Type x)
{
Insert(root,x);
}
template<class Type>
AVLNode<Type>* AVLTree<Type>::Insert(AVLNode<Type>* & temp,Type x)
{
if(!temp)
{
temp=new AVLNode<Type>;
temp->data=x;
temp->height=1;
temp->left=temp->right=NULL;
if(!root)
root=temp;
}
else if(x<temp->data)
{
temp->left=Insert(temp->left,x);
if(GetHeight(temp->left)-GetHeight(temp->right)==2)
{
if(x<temp->left->data)
temp=LeftLeftRotation(temp);
else
temp=LeftRightRotation(temp);
}
}
else if(x>temp->data)
{
temp->right=Insert(temp->right,x);
if(GetHeight(temp->right)-GetHeight(temp->left)==2)
{
if(x<temp->right->data)
temp=RightLeftRotation(temp);
else
temp=RightRightRotation(temp);
}
}
else
{
std::cout<<"We could not insert a same number into a binary search tree!"<<std::endl;
return NULL;
}
temp->height=MAX(GetHeight(temp->left),GetHeight(temp->right))+1;
return temp;
}
template<class Type>
void AVLTree<Type>::Remove(Type x)
{
root=Remove(root,x);
}
template<class Type>
AVLNode<Type>* AVLTree<Type>::Remove(AVLNode<Type>*& temp,Type x)
{
AVLNode<Type>* temprelease;
if(x<temp->data)
{
temp->left=Remove(temp->left,x);
temp->height=MAX(GetHeight(temp->left),GetHeight(temp->right))+1;
if(GetHeight(temp->right)-GetHeight(temp->left)==2)
{
temprelease=temp->right;
if(GetHeight(temprelease->left)>GetHeight(temprelease->right))
temp=RightLeftRotation(temp);
else
temp=RightRightRotation(temp);
}
}
else if(x>temp->data)
{
temp->right=Remove(temp->right,x);
temp->height=MAX(GetHeight(temp->left),GetHeight(temp->right))+1;
if(GetHeight(temp->left)-GetHeight(temp->right)==2)
{
temprelease=temp->left;
if(GetHeight(temprelease->left)>GetHeight(temprelease->right))
temp=LeftLeftRotation(temp);
else
temp=LeftRightRotation(temp);
}
}
else
{
if(temp->left&&temp->right)
{
if(GetHeight(temp->left)>GetHeight(temp->right))
{
temprelease=FindMax(temp->left);
temp->data=temprelease->data;
temp->left=Remove(temp->left,temprelease->data);
temp->left->height=MAX(GetHeight(temp->left->left),GetHeight(temp->left->right))+1;
temp->height=MAX(GetHeight(temp->left),GetHeight(temp->right))+1;
temprelease=NULL;
}
else
{
temprelease=FindMin(temp->right);
temp->data=temprelease->data;
temp->right=Remove(temp->right,temprelease->data);
temp->right->height=MAX(GetHeight(temp->right->left),GetHeight(temp->right->right))+1;
temp->height=MAX(GetHeight(temp->left),GetHeight(temp->right))+1;
temprelease=NULL;
}
}
else
{
AVLNode<Type>* temprelease1=temp;
temp=temp->left?temp->left:temp->right;
delete temprelease1;
}
}
//temp->height=MAX(GetHeight(temp->left),GetHeight(temp->right))+1;
return temp;
}
template<class Type>
AVLNode<Type>* AVLTree<Type>::LeftLeftRotation(AVLNode<Type>* k1)
{
AVLNode<Type>* k2=k1->left;
k1->left=k2->right;
k2->right=k1;
k1->height=MAX(GetHeight(k1->left),GetHeight(k1->right))+1;
k2->height=MAX(GetHeight(k2->left),GetHeight(k2->right))+1;
return k2;
}
template<class Type>
AVLNode<Type>* AVLTree<Type>::RightRightRotation(AVLNode<Type>* k1)
{
AVLNode<Type>* k2=k1->right;
k1->right=k2->left;
k2->left=k1;
k1->height=MAX(GetHeight(k1->left),GetHeight(k1->right))+1;
k2->height=MAX(GetHeight(k2->left),GetHeight(k2->right))+1;
return k2;
}
template<class Type>
AVLNode<Type>* AVLTree<Type>::LeftRightRotation(AVLNode<Type>* k1)
{
k1->left=RightRightRotation(k1->left);
return LeftLeftRotation(k1);
}
template<class Type>
AVLNode<Type>* AVLTree<Type>::RightLeftRotation(AVLNode<Type>* k1)
{
k1->right=LeftLeftRotation(k1->right);
return RightRightRotation(k1);
}
template<class Type>
void AVLTree<Type>::PreOrderTraversal(AVLNode<Type>* temproot)
{
if(!temproot)
return;
std::cout<<temproot->data<<" ";
PreOrderTraversal(temproot->left);
PreOrderTraversal(temproot->right);
}
template<class Type>
void AVLTree<Type>::PreOrderTraversal()
{
PreOrderTraversal(root);
}
template<class Type>
AVLNode<Type>* AVLTree<Type>::FindMin(AVLNode<Type>* temp)
{
while(temp)
{
if(!temp->left)
return temp;
else
temp=temp->left;
}
return NULL;
}
template<class Type>
AVLNode<Type>* AVLTree<Type>::FindMax(AVLNode<Type>* temp)
{
while(temp)
{
if(!temp->right)
return temp;
else
temp=temp->right;
}
return NULL;
}
#endif