9. avltree

fatal.h

#include <stdio.h>
#include <stdlib.h>

#define Error(Str)        FatalError(Str)
#define FatalError(Str)   fprintf(stderr, "%s\n", Str), exit(1)

avltree.h

typedef int ElementType;

#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);

void PreorderTraversal(AvlTree T);
void InorderTraversal(AvlTree T);
void PostorderTraversal(AvlTree T);
void LevelorderTraversal(AvlTree T);

#endif  /* _AvlTree_H */

queue.h

#ifndef _Queue_h
#define _Queue_h

struct QueueRecord;
typedef struct QueueRecord *Queue;

int IsEmptyQueue(Queue Q);
int IsFullQueue(Queue Q);
Queue CreateQueue(int MaxElements);
void DisposeQueue(Queue Q);
void MakeEmptyQueue(Queue Q);
void Enqueue(AvlTree X, Queue Q);
AvlTree Front(Queue Q);
void Dequeue(Queue Q);
AvlTree FrontAndDequeue(Queue Q);

#endif  

avltree.c

#include "avltree.h"
#include "queue.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;
}

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;
}

static int Height(Position P)
{
    if (P == NULL)
        return -1;
    else
        return P->Height;
}

static int Max(int Lhs, int Rhs)
{
    return Lhs > Rhs ? Lhs : Rhs;
}

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

    K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;
    K1->Height = Max(Height(K1->Left), K2->Height) + 1;

    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;

    K1->Height = Max(Height(K1->Left), Height(K1->Right)) + 1;
    K2->Height = Max(Height(K2->Right), K1->Height) + 1;

    return K2;  /* New root */
}

/* 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 */
static Position DoubleRotateWithLeft(Position K3)
{
    /* Rotate between K1 and K2 */
    K3->Left = SingleRotateWithRight(K3->Left);

    /* Rotate between K3 and K2 */
    return SingleRotateWithLeft(K3);
}

/* 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 */
static Position DoubleRotateWithRight(Position K1)
{
    /* Rotate between K3 and K2 */
    K1->Right = SingleRotateWithLeft(K1->Right);

    /* Rotate between K1 and K2 */
    return SingleRotateWithRight(K1);
}

AvlTree Insert(ElementType X, AvlTree T)
{
    if (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)
        {
            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);
        }
    }
    /* Else X is in the tree already; we'll do nothing */

    T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
    return T;
}

AvlTree Delete(ElementType X, AvlTree T)
{
    Position TmpCell;

    if (T == NULL)
        Error("Element not found");
    else if (X < T->Element)  /* Go left */
        T->Left = Delete(X, T->Left);
    else if (X > T->Element)  /* Go right */
        T->Right = Delete(X, T->Right);

    /* Found element to be deleted */
    else if (T->Left && T->Right)  /* Two children */
    {
        /* Replace with smallest in right subtree */
        TmpCell = FindMin(T->Right);
        T->Element = TmpCell->Element;
        T->Right = Delete(T->Element, T->Right);
    }
    else  /* One or zero children */
    {
        TmpCell = T;
        if (T->Left == NULL) /* Also handles 0 children */
            T = T->Right;
        else if (T->Right == NULL)
            T = T->Left;
        free(TmpCell);
    }

    if (T != NULL)
    {
        if (Height(T->Left) - Height(T->Right) == 2)
        {
            if (Height(T->Left->Left) >= Height(T->Left->Right))
                T = SingleRotateWithLeft(T);
            else
                T = DoubleRotateWithLeft(T);
        }
        else if (Height(T->Right) - Height(T->Left) == 2)
        {
            if (Height(T->Right->Right) >= Height(T->Right->Left))
                T = SingleRotateWithRight(T);
            else
                T = DoubleRotateWithRight(T);
        }

        T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
    }

    return T;
}

ElementType Retrieve(Position P)
{
    return P->Element;
}

void PreorderTraversal(AvlTree T)
{
    if (T != NULL)
    {
        printf("%d\t", T->Element);
        PreorderTraversal(T->Left);
        PreorderTraversal(T->Right);
    }
}

void InorderTraversal(AvlTree T)
{
    if (T != NULL)
    {
        InorderTraversal(T->Left);
        printf("%d\t", T->Element);
        InorderTraversal(T->Right);
    }
}

void PostorderTraversal(AvlTree T)
{
    if (T != NULL)
    {
        PostorderTraversal(T->Left);
        PostorderTraversal(T->Right);
        printf("%d\t", T->Element);
    }
}

void LevelorderTraversal(AvlTree T)
{
    Queue Q;
    AvlTree TmpCell;

    if (T == NULL)
        return;

    Q = CreateQueue(80);
    Enqueue(T, Q);
    while (!IsEmptyQueue(Q))
    {
        TmpCell = FrontAndDequeue(Q);
        printf("%d\t", TmpCell->Element);
        if (TmpCell->Left != NULL)
            Enqueue(TmpCell->Left, Q);
        if (TmpCell->Right != NULL)
            Enqueue(TmpCell->Right, Q);
    }
}

queue.c

#include "avltree.h"
#include "queue.h"
#include "fatal.h"
#include <stdlib.h>

#define MinQueueSize ( 5 )

struct QueueRecord
{
    int Capacity;
    int Front;
    int Rear;
    int Size;
    AvlTree *Array;
};

int IsEmptyQueue(Queue Q)
{
    return Q->Size == 0;
}

int IsFullQueue(Queue Q)
{
    return Q->Size == Q->Capacity;
}

Queue CreateQueue(int MaxElements)
{
    Queue Q;

    if (MaxElements < MinQueueSize)
        Error("Queue size is too small");

    Q = malloc(sizeof(struct QueueRecord));
    if (Q == NULL)
        FatalError("Out of space!!!");

    Q->Array = malloc(sizeof(AvlTree) * MaxElements);
    if (Q->Array == NULL)
        FatalError("Out of space!!!");
    Q->Capacity = MaxElements;
    MakeEmptyQueue(Q);

    return Q;
}

void MakeEmptyQueue(Queue Q)
{
    Q->Size = 0;
    Q->Front = 1;
    Q->Rear = 0;
}

void DisposeQueue(Queue Q)
{
    if (Q != NULL)
    {
        free(Q->Array);
        free(Q);
    }
}

static int Succ(int Value, Queue Q)
{
    if (++Value == Q->Capacity)
        Value = 0;
    return Value;
}

void Enqueue(AvlTree X, Queue Q)
{
    if (IsFullQueue(Q))
        Error("Full queue");
    else
    {
        Q->Size++;
        Q->Rear = Succ(Q->Rear, Q);
        Q->Array[Q->Rear] = X;
    }
}

AvlTree Front(Queue Q)
{
    if (!IsEmptyQueue(Q))
        return Q->Array[Q->Front];
    Error("Empty queue");
    return 0;  /* Return value used to avoid warning */
}

void Dequeue(Queue Q)
{
    if (IsEmptyQueue(Q))
        Error("Empty queue");
    else
    {
        Q->Size--;
        Q->Front = Succ(Q->Front, Q);
    }
}

AvlTree FrontAndDequeue(Queue Q)
{
    AvlTree X = 0;

    if (IsEmptyQueue(Q))
        Error("Empty queue");
    else
    {
        Q->Size--;
        X = Q->Array[Q->Front];
        Q->Front = Succ(Q->Front, Q);
    }
    return X;
}

testavl.c

#include "avltree.h"
#include "queue.h"
#include <stdio.h>

int main()
{
    AvlTree T;
    int i;
    int j = 0;

    T = MakeEmpty(NULL);
    printf("Insert:\n");
    for (i = 0; i < 50; i++, j = (j + 7) % 50)
    {
        printf("%d\t", j);
        T = Insert(j, T);
    }
    printf("\n先序遍历:\n");
    PreorderTraversal(T);
    printf("\n中序遍历:\n");
    InorderTraversal(T);
    printf("\n后序遍历:\n");
    PostorderTraversal(T);
    printf("\n层序遍历:\n");
    LevelorderTraversal(T);
    printf("\n\n");

    printf("Delete:\n");
    for (i = 0; i < 50; i += 2)
    {
        printf("%d\t", i);
        T = Delete(i, T);
    }
    printf("\n先序遍历:\n");
    PreorderTraversal(T);
    printf("\n中序遍历:\n");
    InorderTraversal(T);
    printf("\n后序遍历:\n");
    PostorderTraversal(T);
    printf("\n层序遍历:\n");
    LevelorderTraversal(T);
    printf("\n\n");

    printf("Min is %d, Max is %d\n", Retrieve(FindMin(T)), Retrieve(FindMax(T)));

    return 0;
}
posted @ 2017-01-10 17:21  typewriter  阅读(294)  评论(0编辑  收藏  举报