AVL树是在二叉查找树的基础上加了一个平衡条件,目的是为了防止二叉查找树在某一边的深度过大而使效率降低
AVL树的关键是两个单旋转:左旋转和右旋转
双旋转也就是这两个旋转的组合
旋转的话 用图是最好解释的 下面用从别人那里盗来的图来说明下吧
想搞明白的话,自己照着这个图里面的画一画就差不多了
那么下面我就上代码了:
头文件:
#ifndef AVLTREE_H_INCLUDED
#define AVLTREE_H_INCLUDED
struct AvlNode;
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree;
typedef double ElementType;
AvlTree MakeEmpty(AvlTree T);
Position Find(ElementType X,AvlTree T);
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
AvlTree Insert(ElementType X,AvlTree T);
AvlTree Delete(ElementType X,AvlTree T);
ElementType Retrieve(Position P); //如果是采用懒惰删除,则可以实现这个方法用以恢复
#endif // AVLTREE_H_INCLUDED
实现:
#include "AVLTree.h"
#include <stdio.h>
#include <stdlib.h>
struct AvlNode
{
ElementType Element;
AvlTree Left;
AvlTree Right;
int Height;
};
static int Height(Position P)
{
if(P == NULL)
return -1;
else
return P->Height;
}
static int Max(int H1,int H2)
{
if(H1 > H2)
return H1;
else
return H2;
}
static void FatalError(char * s)
{
}
static void Error(char * s)
{
}
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),K2->Height)+1;
return K1;
}
static Position SingleRotateWithRight(Position K1)
{
Position K2;
K2 = K1->Right;
K1->Right = K2->Left;
K2->Left = K1;
K1->Height = Max(Height(K1->Right),Height(K1->Left))+1;
K2->Height = Max(Height(K2->Right),K1->Height)+1;
return K2;
}
static Position DoubleRotateWithLeft(Position K3)
{
K3->Left = SingleRotateWithLeft(K3->Left);
return SingleRotateWithRight(K3);
}
static Position DoubleRotateWithRight(Position K1)
{
K1->Right = SingleRotateWithRight(K1->Right);
return SingleRotateWithLeft(K1);
}
Position Find(ElementType X,AvlTree T)
{
if(T == NULL)
return NULL;
else if(X > T->Element)
return Find(X,T->Right);
else if(X < T->Element)
return Find(X,T->Left);
else
return T;
}
Position FindMax(AvlTree T)
{
if(T != NULL)
while(T->Right != NULL)
T = T->Right;
return T;
}
Position FindMin(AvlTree T)
{
if(T != NULL)
while(T->Left != NULL)
T = T->Left;
return T;
}
AvlTree Insert(ElementType X,AvlTree T)
{
if(T == NULL)
{
T = malloc(sizeof(struct AvlNode));
if(T == NULL)
FatalError("Out of space!!!");
else
{
T->Element = X;
T->Height = 0;
T->Left = T->Right = NULL;
}
// printf("%lf\n",T->Element);
}
else if(X < T->Element)
{
T->Left = Insert(X,T->Left);
if(Height(T->Left)-Height(T->Right) == 2)
if(X < T->Left->Element)
T = SingleRotateWithLeft(T);
else
T = DoubleRotateWithRight(T);
}
else if(X > T->Element)
{
T->Right = Insert(X,T->Right);
if(Height(T->Right)-Height(T->Left)==2)
if(X > T->Right->Element)
T = SingleRotateWithRight(T);
else
T = DoubleRotateWithRight(T);
}
T->Height = Max(Height(T->Left),Height(T->Right))+1;
return T;
}
AvlTree Delete(ElementType X,AvlTree T)
{
Position TmpCell;
if(T == NULL)
Error("Element not found");
else if(X > T->Element)
Delete(X,T->Right);
else if(X < T->Element)
Delete(X,T->Left);
else if(T->Left && T->Right)
{
TmpCell = FindMin(T->Right);
T->Element = TmpCell->Element;
T->Right = Delete(T->Element,T->Right);
T->Height = Max(T->Left->Height,Height(T->Right))+1;
if(T->Left->Height - T->Right->Height == 2)
{
if(T->Left->Left->Height > T->Left->Right->Height)
SingleRotateWithLeft(T);
else
DoubleRotateWithLeft(T);
}
}
else
{
TmpCell = T;
ElementType Tmp;
if(T->Right == NULL)
T = T->Left;
else if(T->Left == NULL)
T = T->Right;
free(TmpCell);
T->Height = (Height(T->Left),Height(T->Right))+1;
}
return T;
}
AvlTree MakeEmpty(AvlTree T)
{
}
int main()
{
AvlTree T = NULL;
AvlTree T2 = NULL;
T = Insert(1.01,T);
Insert(2,T);
printf("%lf\n",T->Element);
Position P = FindMax(T);
printf("%lf\n",P->Element);
return 0;
}
同样在最后加了一个main函数用于测试,编译器是gcc
PS:代码改编自《数据结构与算法分析第二版》,因为自己在改了一些,所以不保证没有BUG(因为书上的代码是ANSI C,有些用gcc过不了)

本文深入探讨AVL树的概念及其关键操作——左旋和右旋,并提供了详细的代码实现,帮助读者理解如何维持树的平衡。
5618

被折叠的 条评论
为什么被折叠?



