本文用C语言实现平衡书,平衡树相对一般的二叉查找树而言效率稍高,以下是源代码:
#include "AvlTree.h"
#include "malloc.h"
AvlTree CreatAvlTree(void)
{
return NULL;
}
AvlTree MakeEmpty(AvlTree T)
{
if (T != NULL)
{
MakeEmpty(T->Left);
MakeEmpty(T->Right);
free(T);
}
return NULL;
}
Position Find(AvlTree T, ElementType X)
{
if (T == NULL)
{
printf("Element X is not in the search_tree!\r\n");
return NULL;
}
if (X < T->Element)
{
return Find(T->Left, X);
}
else if (X>T->Element)
{
return Find(T->Right, X);
}
else
{
return T;
}
}
Position FindMax(AvlTree T)
{
while (T->Right != NULL)
{
T = T->Right;
}
return T;
}
Position FindMin(AvlTree T)
{
while (T->Left != NULL)
{
T = T->Left;
}
return T;
}
int32_t Height(AvlTree T)
{
if (T == NULL)
{
return -1;
}
else
{
return T->Height;
}
}
/*返回二者中较大的*/
static int32_t Max(int32_t a, int32_t b)
{
return a > b ? a : b;
}
/*修复情况一:对某节点的左儿子的左子树进行一次插入*/
static Position SingleRotaWithLeft(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 SingleRotaWithRight(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;
}
/*修复情况二:对某节点的左儿子的右子树进行一次插入*/
static Position DoubleRotaWithLeft(Position K3)
{
K3->Left = SingleRotaWithRight(K3->Left);
return SingleRotaWithLeft(K3);
}
/*修复情况三:对某节点的右儿子的左子树进行一次插入*/
static Position DoubleRotaWithRight(Position K1)
{
K1->Right = SingleRotaWithLeft(K1->Right);
return SingleRotaWithRight(K1);
}
AvlTree Insert(AvlTree T, ElementType X)
{
if (T == NULL)
{
T = (Position)malloc(sizeof(AvlTreeNode));
if (T == NULL)
{
printf("Out of space!!!\r\n");
}
else
{
T->Element = X;
T->Height = 0;
T->Left = T->Right = NULL;
}
}
else if (X < T->Element)
{
T->Left = Insert(T->Left, X);
if (2 == (Height(T->Left) - Height(T->Right)))
{
if (X < T->Left->Element)
T = SingleRotaWithLeft(T);
else
T = DoubleRotaWithLeft(T);
}
}
else if (X > T->Element)
{
T->Right = Insert(T->Right, X);
if (2 == (Height(T->Right) - Height(T->Left)))
{
if (X > T->Right->Element)
T = SingleRotaWithRight(T);
else
T = DoubleRotaWithRight(T);
}
}
T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
return T;
}
void PrintAllNodeRising(AvlTree T)
{
if (T == NULL)
{
return;
}
PrintAllNodeRising(T->Left);
printf("%d\r\n", T->Element);
PrintAllNodeRising(T->Right);
}
void PrintAllNodeFalling(AvlTree T)
{
if (T == NULL)
{
return;
}
PrintAllNodeFalling(T->Right);
printf("%d\r\n", T->Element);
PrintAllNodeFalling(T->Left);
}
static void PrintNodeName(AvlTree T, uint32_t Depth)
{
for (uint16_t i = 0; i < Depth; i++)
{
putchar(' ');
}
printf("*%d*--%d\r\n", Depth, T->Element);
}
static void PrintNode(AvlTree T, uint32_t Depth)
{
if (T != NULL)
{
PrintNodeName(T, Depth);
PrintNode(T->Left, Depth + 1);
PrintNode(T->Right, Depth + 1);
}
}
void PrintAllNode(AvlTree T)
{
PrintNode(T, 0);
}
#ifndef __AVLTREE_H_
#define __AVLTREE_H_
#include "stdint.h"
#include <stdio.h>
#include <stdbool.h>
typedef int64_t ElementType;
typedef struct node
{
ElementType Element;
struct node *Left;
struct node *Right;
int32_t Height;
} AvlTreeNode;
typedef AvlTreeNode *PtrToNode;
typedef PtrToNode AvlTree;
typedef PtrToNode Position;
AvlTree CreatAvlTree(void);
AvlTree MakeEmpty(AvlTree T);
Position Find(AvlTree T, ElementType X);
Position FindMax(AvlTree T);
Position FindMin(AvlTree T);
int32_t Height(AvlTree T);
AvlTree Insert(AvlTree T, ElementType X);
AvlTree Delete(AvlTree T, ElementType X);
ElementType Retrieve(Position P);
void PrintAllNodeRising(AvlTree T);
void PrintAllNodeFalling(AvlTree T);
void PrintAllNode(AvlTree T);
#endif