分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击人工智能教程
/*
* Fatal.h - by FreeMan
*/
#include <stdio.h>
#include <stdlib.h>
#define Error( Str ) FatalError( Str )
#define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 )
/*
* AaTree.h - by FreeMan
*/
typedef int ElementType;
#ifndef _AATree_H_
#define _AATree_H_
struct AANode;
typedef struct AANode *Position;
typedef struct AANode *AATree;
AATree MakeAaTreeEmpty(AATree T);
Position FindInAaTree(ElementType X, AATree T);
Position FindMinInAaTree(AATree T);
Position FindMaxInAaTree(AATree T);
AATree InitializeAaTree(void);
AATree InsertInAaTree(ElementType X, AATree T);
AATree RemoveInAaTree(ElementType X, AATree T);
ElementType RetrieveInAaTree(Position P);
extern Position NullNode;
#endif
/*
* AaTree.c - by FreeMan
*/
#include "AaTree.h"
#include "Fatal.h"
#include <stdlib.h>
Position NullNode = NULL; /* Needs more initialization */
struct AANode
{
ElementType Element;
AATree Left;
AATree Right;
int Level;
};
AATree InitializeAaTree(void)
{
if (NullNode == NULL)
{
NullNode = malloc(sizeof(struct AANode));
if (NullNode == NULL)
{
FatalError("Out of memory!!");
}
NullNode->Left = NullNode->Right = NullNode;
NullNode->Level = 0;
}
return NullNode;
}
AATree MakeAaTreeEmpty(AATree T)
{
if (T != NullNode)
{
MakeAaTreeEmpty(T->Left);
MakeAaTreeEmpty(T->Right);
free(T);
}
return NullNode;
}
Position FindInAaTree(ElementType X, AATree T)
{
if (T == NullNode)
{
return NullNode;
}
if (X < T->Element)
{
return FindInAaTree(X, T->Left);
}
else if (X > T->Element)
{
return FindInAaTree(X, T->Right);
}
else
{
return T;
}
}
Position FindMinInAaTree(AATree T)
{
if (T == NullNode)
{
return NullNode;
}
else if (T->Left == NullNode)
{
return T;
}
else
{
return FindMinInAaTree(T->Left);
}
}
Position FindMaxInAaTree(AATree T)
{
if (T != NullNode)
{
while (T->Right != NullNode)
{
T = T->Right;
}
}
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 heights, then return new root.
*/
static Position SingleRotateWithLeft(Position K2)
{
Position K1;
K1 = K2->Left;
K2->Left = K1->Right;
K1->Right = K2;
return K1; /* New root */
}
/*
* 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.
*/
static Position SingleRotateWithRight(Position K1)
{
Position K2;
K2 = K1->Right;
K1->Right = K2->Left;
K2->Left = K1;
return K2; /* New root */
}
/* If T's left child is on the same level as T, perform a rotation. */
AATree Skew(AATree T)
{
if (T->Left->Level == T->Level)
{
T = SingleRotateWithLeft(T);
}
return T;
}
/* If T's rightmost grandchild is on the same level, rotate right child up. */
AATree Split(AATree T)
{
if (T->Right->Right->Level == T->Level)
{
T = SingleRotateWithRight(T);
T->Level++;
}
return T;
}
AATree InsertInAaTree(ElementType Item, AATree T)
{
if (T == NullNode)
{
/* Create and return a one-node tree */
T = malloc(sizeof(struct AANode));
if (T == NULL)
{
FatalError("Out of memory!!");
}
else
{
T->Element = Item;
T->Left = T->Right = NullNode;
T->Level = 1;
}
}
else if (Item < T->Element)
{
T->Left = InsertInAaTree(Item, T->Left);
}
else if (Item > T->Element)
{
T->Right = InsertInAaTree(Item, T->Right);
}
/* Otherwise it's a duplicate; do nothing */
T = Skew(T);
T = Split(T);
return T;
}
AATree RemoveInAaTree(ElementType Item, AATree T)
{
static Position DeletePtr, LastPtr;
if (T != NullNode)
{
/* Step 1: Search down tree, set LastPtr and DeletePtr. */
LastPtr = T;
if (Item < T->Element)
{
T->Left = RemoveInAaTree(Item, T->Left);
}
else
{
DeletePtr = T;
T->Right = RemoveInAaTree(Item, T->Right);
}
/* Step 2: If at the bottom of the tree and item is present, we remove it. */
if (T == LastPtr)
{
if (DeletePtr != NullNode && Item == DeletePtr->Element)
{
DeletePtr->Element = T->Element;
DeletePtr = NullNode;
T = T->Right;
free(LastPtr);
}
}
/* Step 3: Otherwise, we are not at the bottom; Rebalance. */
else if (T->Left->Level < T->Level - 1 || T->Right->Level < T->Level - 1)
{
if (T->Right->Level > --T->Level)
{
T->Right->Level = T->Level;
}
T = Skew(T);
T->Right = Skew(T->Right);
T->Right->Right = Skew(T->Right->Right);
T = Split(T);
T->Right = Split(T->Right);
}
}
return T;
}
ElementType RetrieveInAaTree(Position P)
{
return P->Element;
}
/*
* AaTreeTest.c - by FreeMan
*/
#include "AaTree.h"
#include <stdio.h>
#define NumItems 20
main()
{
printf("Testing AA Tree...\n");
AATree T;
Position P;
int i;
int j = 0;
T = InitializeAaTree();
T = MakeAaTreeEmpty(NullNode);
for (i = 0; i < NumItems; i++, j = (j + 7) % NumItems)
{
T = InsertInAaTree(j, T);
}
for (i = 0; i < NumItems; i++)
{
if ((P = FindInAaTree(i, T)) == NullNode || RetrieveInAaTree(P) != i)
{
printf("Error at %d\n", i);
}
}
for (i = 0; i < NumItems; i += 2)
{
T = RemoveInAaTree(i, T);
}
for (i = 1; i < NumItems; i += 2)
{
if ((P = FindInAaTree(i, T)) == NullNode || RetrieveInAaTree(P) != i)
{
printf("Error at %d\n", i);
}
}
for (i = 0; i < NumItems; i += 2)
{
if ((P = FindInAaTree(i, T)) != NullNode)
{
printf("Error at %d\n", i);
}
}
printf("Min is %d, Max is %d\n", RetrieveInAaTree(FindMinInAaTree(T)), RetrieveInAaTree(FindMaxInAaTree(T)));
return 0;
}
// Output:
/*
Testing AA Tree...
Min is 1, Max is 19
*/