avltree.h
#ifndef _AVLTREE_H_
#define _AVLTREE_H_
struct AvlNode;
typedef struct AvlNode* Position;
typedef struct AvlNode* AvlTree;
typedef int ElementType;
AvlTree Insert(ElementType x, AvlTree T);
AvlTree MakeEmpty(AvlTree T);
Position Find(ElementType X, AvlTree T);
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
AvlTree Delete(ElementType X, AvlTree T);
ElementType Retrieve(Position P);
void InOrder(AvlTree T,void(*pfun)(ElementType T));
#endif
avltree.c
#include<stdio.h>
#include<stdlib.h>
#include"avltree.h"
struct AvlNode
{
ElementType Element;
AvlTree Left;
AvlTree Right;
int Height;
};
static int Height(Position P);
static int Max(int a, int b) { return a > b ? a : b; }
static Position SingleRotateWithLeft(Position K2);
static Position DoubleRotateWithLeft(Position K3);
static Position SingleRotateWithRight(Position K2);
static Position DoubleRotateWithRight(Position K3);
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;
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;
}
AvlTree Delete(ElementType X, AvlTree T)
{
if (!T)return NULL;
if (X < T->Element)
{
T->Left=Delete(X, T->Left);
if (Height(T->Right) - Height(T->Left) == 2)
{
Position Tright = T->Right;
//右子树的左子树非空,就双旋转
if (Height(Tright->Left)>=0)
T=DoubleRotateWithRight(T);
//if之后可以省略,此处为了明确情形
else if(T->Left==NULL)
T=SingleRotateWithRight(T);
}
else//及时更新树高
T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
}
else if (X > T->Element)
{
T->Right = Delete(X, T->Right);
if (Height(T->Left) - Height(T->Right) == 2)
{
Position Tleft = T->Left;
if (Height(Tleft->Right) >=0)
T=DoubleRotateWithLeft(T);
else if(T->Right==NULL)
T=SingleRotateWithLeft(T);
}
else
T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
}
else
{
if (T->Left&&T->Right)
{
if (Height(T->Left) > Height(T->Right))
{
T->Element = FindMax(T->Left)->Element;
T->Left = Delete(T->Element, T->Left);
}
else
{
T->Element = FindMin(T->Right)->Element;
T->Right = Delete(T->Element, T->Right);
}
}
else
{
Position temp = T;
T = T->Left ? T->Left : T->Right;
free(temp);
}
}
return T;
}
ElementType Retrieve(Position P)
{
if (P != NULL)
return P->Element;
}
AvlTree MakeEmpty(AvlTree T)
{
if (T != NULL)
{
MakeEmpty(T->Left);
MakeEmpty(T->Right);
free(T);
}
return NULL;
}
void InOrder(AvlTree T, void(*pfun)(ElementType T))
{
if (T != NULL)
{
InOrder(T->Left,pfun);
(*pfun)(T->Element);
InOrder(T->Right,pfun);
}
}
static Position DoubleRotateWithRight(Position K3)
{
K3->Right = SingleRotateWithLeft(K3->Right);
return SingleRotateWithRight(K3);
}
static Position SingleRotateWithRight(Position K2)
{
Position K1;
K1 = K2->Right;
K2->Right = K1->Left;
K1->Left = K2;
K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;
K1->Height = Max(Height(K1->Right), K2->Height) + 1;
return K1;
}
static Position DoubleRotateWithLeft(Position K3)
{
K3->Left = SingleRotateWithRight(K3->Left);
return SingleRotateWithLeft(K3);
}
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;
}
AvlTree Insert(ElementType X, AvlTree T)
{
if (T == NULL)
{
T = (AvlTree)malloc(sizeof(struct AvlNode));
if (T == NULL)
{
printf("FAILURE!\n");
exit(EXIT_FAILURE);
}
else
{
T->Element = X;
T->Left = NULL;
T->Right = NULL;
T->Height = 0;
}
}
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 = DoubleRotateWithLeft(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;
}
static int Height(Position P)
{
if (P == NULL)
return -1;
else
return P->Height;
}