zoukankan      html  css  js  c++  java
  • 9. avltree

    fatal.h

    #include <stdio.h>
    #include <stdlib.h>
    
    #define Error(Str)        FatalError(Str)
    #define FatalError(Str)   fprintf(stderr, "%s
    ", 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->Element);
            PreorderTraversal(T->Left);
            PreorderTraversal(T->Right);
        }
    }
    
    void InorderTraversal(AvlTree T)
    {
        if (T != NULL)
        {
            InorderTraversal(T->Left);
            printf("%d	", T->Element);
            InorderTraversal(T->Right);
        }
    }
    
    void PostorderTraversal(AvlTree T)
    {
        if (T != NULL)
        {
            PostorderTraversal(T->Left);
            PostorderTraversal(T->Right);
            printf("%d	", 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	", 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:
    ");
        for (i = 0; i < 50; i++, j = (j + 7) % 50)
        {
            printf("%d	", j);
            T = Insert(j, T);
        }
        printf("
    先序遍历:
    ");
        PreorderTraversal(T);
        printf("
    中序遍历:
    ");
        InorderTraversal(T);
        printf("
    后序遍历:
    ");
        PostorderTraversal(T);
        printf("
    层序遍历:
    ");
        LevelorderTraversal(T);
        printf("
    
    ");
    
        printf("Delete:
    ");
        for (i = 0; i < 50; i += 2)
        {
            printf("%d	", i);
            T = Delete(i, T);
        }
        printf("
    先序遍历:
    ");
        PreorderTraversal(T);
        printf("
    中序遍历:
    ");
        InorderTraversal(T);
        printf("
    后序遍历:
    ");
        PostorderTraversal(T);
        printf("
    层序遍历:
    ");
        LevelorderTraversal(T);
        printf("
    
    ");
    
        printf("Min is %d, Max is %d
    ", Retrieve(FindMin(T)), Retrieve(FindMax(T)));
    
        return 0;
    }
    
  • 相关阅读:
    js实现图片轮播(修改版1)
    动态添加内容到滚动区域
    新闻自动滚动
    多媒体对象(Media Object)
    (Py练习)判断能被几个9整除
    (Py练习)输出乘法口诀表
    (Py练习)输入某年某月判断天数
    文件名称批量修改
    续订Jetbrain学生包
    (Py练习)判断101-200之间的素数个数并输出
  • 原文地址:https://www.cnblogs.com/typewriter/p/6270158.html
Copyright © 2011-2022 走看看