AVL 平衡树源码笔记
avltree.h
typedef int ElementType;
/* START: fig4_35.txt */
#ifndef _AvlTree_H
#define _AvlTree_H
struct AvlNode;
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree;
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 */
/* END */
avltree.c
#include "avltree.h"
#include <stdlib.h>
#include "fatal.h"
struct AvlNode
{
ElementType Element;
AvlTree Left;
AvlTree Right;
int Height; // 高度
};
// 创建一棵空树
AvlTree
MakeEmpty(AvlTree T)
{
if (T != NULL)
{
MakeEmpty(T->Left);
MakeEmpty(T->Right);
free(T);
}
return NULL;
}
// 查找元素,和 BST 操作相同
Position
Find(ElementType X, AvlTree T)
{
if (T == NULL)
return NULL;
if (X < T->Element)
return Find(X, T->Left);
else if (X > T->Element)
return Find(X, T->Right);
else
return T;
}
// 查找最小值
Position
FindMin(AvlTree T)
{
if (T == NULL)
return NULL;
else if (T->Left == NULL)
return T;
else
return FindMin(T->Left);
}
// 查找最大值
Position
FindMax(AvlTree T)
{
if (T != NULL)
while (T->Right != NULL)
T = T->Right;
return T;
}
/* START: fig4_36.txt */
// 返回树的高度
static int
Height(Position P)
{
if (P == NULL)
return -1;
else
return P->Height;
}
/* END */
// 返回两个数中较大的那一个
static int
Max(int Lhs, int Rhs) // Lhs --> Left hand side Rhs --> Right hand side
{
return Lhs > Rhs ? Lhs : Rhs;
}
/* START: fig4_39.txt */
/* This function can be called only if K2 has a left child */
/* Perform a rotate between a node (K2) and its left child */
/* Update heights, then return new root */
// LL 单旋转
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; /* New root 新的根节点 */
}
/* END */
/* This function can be called only if K1 has a right child */
/* Perform a rotate between a node (K1) and its right child */
/* Update heights, then return new root */
// RR 单旋转
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(Height(K2->Right), K1->Height) + 1;
return K2; /* New root */
}
/* START: fig4_41.txt */
/* This function can be called only if K3 has a left */
/* child and K3's left child has a right child */
/* Do the left-right double rotation */
/* Update heights, then return new root */
// LR 双旋转
static Position
DoubleRotateWithLeft(Position K3)
{
/* Rotate between K1 and K2 */
K3->Left = SingleRotateWithRight(K3->Left); // 先进行 RR 旋转
/* Rotate between K3 and K2 */
return SingleRotateWithLeft(K3); // 然后进行 LL 旋转
}
/* END */
/* This function can be called only if K1 has a right */
/* child and K1's right child has a left child */
/* Do the right-left double rotation */
/* Update heights, then return new root */
// RL 双旋转
static Position
DoubleRotateWithRight(Position K1)
{
/* Rotate between K3 and K2 */
K1->Right = SingleRotateWithLeft(K1->Right);
/* Rotate between K1 and K2 */
return SingleRotateWithRight(K1);
}
/* START: fig4_37.txt */
// 插入操作
AvlTree
Insert(ElementType X, AvlTree T)
{
if (T == NULL) // T 为 NULL 的情况
{
/* Create and return a one-node tree */
T = malloc(sizeof(struct AvlNode));
if (T == NULL)
FatalError("Out of space!!!"); // 空间不足
else
{
T->Element = X;
T->Height = 0;
T->Left = T->Right = NULL;
}
} else if (X < T->Element)
{
T->Left = Insert(X, T->Left);
if (Height(T->Left) - Height(T->Right) == 2) // 平衡因子为 2
if (X < T->Left->Element) // LL 情况
T = SingleRotateWithLeft(T);
else // LR 情况
T = DoubleRotateWithLeft(T);
} else if (X > T->Element)
{
T->Right = Insert(X, T->Right);
if (Height(T->Right) - Height(T->Left) == 2) // RR 情况
if (X > T->Right->Element)
T = SingleRotateWithRight(T);
else // RL 情况
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;
}
/* END */
// 这里应该作 lazy delete,但是这里并没有实现任何删除操作
AvlTree
Delete(ElementType X, AvlTree T)
{
printf("Sorry; Delete is unimplemented; %d remains\n", X);
return T;
}
// 取出节点的元素
ElementType
Retrieve(Position P)
{
return P->Element;
}
main.c(testavl.c 测试函数)
#include "avltree.h"
#include <stdio.h>
int main()
{
AvlTree T;
Position P;
int i;
int j = 0;
T = MakeEmpty( NULL );
for( i = 0; i < 50; i++, j = ( j + 7 ) % 50 ) // 插入数据
T = Insert( j, T );
for( i = 0; i < 50; i++ ) // 测试上面的插入操作是否正确
if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )
printf( "Error at %d\n", i );
// 注释中的时测试删除操作,但是我们并没有实现删除操作,所以暂时不表
/* for( i = 0; i < 50; i += 2 )
T = Delete( i, T );
for( i = 1; i < 50; i += 2 )
if( ( P = Find( i, T ) ) == NULL || Retrieve( P ) != i )
printf( "Error at %d\n", i );
for( i = 0; i < 50; i += 2 )
if( ( P = Find( i, T ) ) != NULL )
printf( "Error at %d\n", i );
*/
// 测试取出最小值和最大值的操作
printf( "Min is %d, Max is %d\n", Retrieve( FindMin( T ) ),
Retrieve( FindMax( T ) ) );
return 0;
}
测试结果:
定义错误的头文件 fatal.h
#include <stdio.h>
#include <stdlib.h>
#define Error(Str) FatalError( Str )
#define FatalError(Str) fprintf( stderr, "%s\n", Str ), exit( 1 )