Data Structure - AA Tree (C)

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击人工智能教程

/*
 * 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

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值