AVL树
在BST的基础上添加平衡操作,使得最坏的情况得到优化。
static int Height(Position P)
{
if(P == NULL)
{
return -1;//默认空节点的高度是-1,一种约定
}
else
{
return P->Height;
}
}
AVL树的插入有四种基本的情况,插入是就要按特征进行归类
AvlTree Insert(int X, AvlTree T)
{
if(T == NULL)
//create and return a one-node tree
{
T = malloc(sizeof(struct AvlNode));
if(T == NULL)
{
printf("Out of Space\n");
exit(EXIT_FAILURE);
}
else
{
T->num = X;
T->Height = 0;
T->Left = T->Right = NULL;
}
}
else if(X < T->num)
{
T->Left = Insert(X, T->Left);
if(Height(T->Left) - Height(T->Right) == 2)
{
if(X < T->Left->num)
{
T = SingleRotateWithLeft(T);
}
else
{
T = DoubleRotateWithLeft(T);
}
}
}
else if(X > T->num)
{
T->Right = Insert(X, T->Right);
if(Height(T->Right) - Height(T->Left) == 2)
{
if(X > T->Right->num)
{
T = SingleRotateWithRight(T);
}
else
{
T = DoubleRotateWithRight(T);
}
}
}
//Else X is in the tree already, we'll do nothing
T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
return T;
}
对应的旋转操作
//This function can be called only if K2 has a left child
//Perform a rotate between a node (K2) and its left child
//Update height, then return new root
static Position SingleRotateWithLeft(Position K2)
{
Position K1;
K1 = K2->Left;
K2->Left = K1->Right;
K1->Right = K2;
K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;
K1->Height = Max(Height(K1->Left), Height(K1->Right)) + 1;
return K1;//New root
}
//This function can be called only if K3 has a child
//child and K3's left child has a right child
//Do the left-right double rotate
//Update heights, then return new root
static Position DoubleRotateWithLeft(Position K3)
{
//Rotate between K1 and K2
K3->Left = SingleRotateWithRight(K3->Left);
//Rotate between K3 and K2
return SingleRotateWithLeft(K3);
}
int Retrieve(Position P)
{
return P->num;
}
static Position SingleRotateWithRight(Position K1)
{
Position K2;
K2 = K1->Right;
K1->Right = K2->Left;
K2->Left = K1;
K1->Height = Max(Height(K1->Left), Height(K1->Right)) + 1;
K2->Height = Max(K1->Height, Height(K2->Right)) + 1;
return K2;
}
static Position DoubleRotateWithRight(Position K3)
{
K3->Right = SingleRotateWithLeft(K3->Right);
return SingleRotateWithRight(K3);
}
重平衡
旋转操作的模块化写法
static Position Fix(Position K2)
{
if(Height(K2->Left) > Height(K2->Right))
{
//K2左儿子的左儿子的高度大于K2的左儿子的右儿子的高度, 执行左单旋转, 否则执行左-右双旋转
if(Height(K2->Left->Left) > Height(K2->Left->Right))
{
K2 = SingleRotateWithLeft(K2);
}
else if(Height(K2->Left->Left) < Height(K2->Left->Right))
{
K2 = DoubleRotateWithLeft(K2);
}
}
else if(Height(K2->Left) < Height(K2->Right))
{
//K2右儿子的右儿子的高度大于K2的右儿子的左儿子的高度, 执行右单旋转, 否则执行右-左双旋转
if(Height(K2->Right->Right) > Height(K2->Right->Left))
{
K2 = SingleRotateWithRight(K2);
}
else if(Height(K2->Right->Right) < Height(K2->Right->Left))
{
K2 = DoubleRotateWithRight(K2);
}
}
return K2;
}
删除的操作基本上和BST一样,只是删除结束后要进行平衡操作
AvlTree Delete(int X, AvlTree T)
{
Position TmpCell;
if(T == NULL)
{
printf("Element not Found\n");
exit(EXIT_FAILURE);
}
else if(X < T->num)
{
T->Left = Delete(X, T->Left);
}
else if(X > T->num)
{
T->Right = Delete(X, T->Right);
}
else if(T->Left && T->Right)
{
TmpCell = FindMin(T->Right);
T->num = TmpCell->num;
T->Right = Delete(T->num, T->Right);
}
else
{
TmpCell = T;
if(T->Left == NULL)
{
T = T->Right;
}
else if(T->Right == NULL)
{
T = T->Left;
}
free(TmpCell);
}
if(T != NULL)
{
//删除完节点之后要更新高度
T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
//在节点T处失去平衡
if((Height(T->Left) - Height(T->Right) >= 2) || (Height(T->Right) - Height(T->Left) >= 2))
{
T = Fix(T);
//修复完成后更新节点高度
T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
}
}
return T;
}
struct AvlNode;
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree;
#define Max(a, b) (a)>(b)?(a):(b)
struct AvlNode
{
int num;
AvlTree Left;
AvlTree Right;
int Height;
};