14. 斜堆(skew heap)

fatal.h

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

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

skewheap.h

typedef int ElementType;

#ifndef _LeftHeap_H
#define _LeftHeap_H

struct TreeNode;
typedef struct TreeNode *PriorityQueue;

PriorityQueue Initialize(void);
ElementType FindMin(PriorityQueue H);
int IsEmpty(PriorityQueue H);
PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2);

#define Insert(X, H) (H = Insert1((X), H))

PriorityQueue Insert1(ElementType X, PriorityQueue H);

#define DeleteMin(H) (MinElement = FindMin(H), H = DeleteMin1(H), MinElement)

PriorityQueue DeleteMin1(PriorityQueue H);

void PreorderTraversal(PriorityQueue H);
void InorderTraversal(PriorityQueue H);
void PostorderTraversal(PriorityQueue H);
void LevelorderTraversal(PriorityQueue H);

#endif

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(PriorityQueue X, Queue Q);
PriorityQueue Front(Queue Q);
void Dequeue(Queue Q);
PriorityQueue FrontAndDequeue(Queue Q);

#endif

skewheap.c

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


struct TreeNode
{
    ElementType   Element;
    PriorityQueue Left;
    PriorityQueue Right;
};

PriorityQueue Initialize(void)
{
    return NULL;
}
static PriorityQueue Merge1(PriorityQueue H1, PriorityQueue H2);

PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2)
{
    if (H1 == NULL)
        return H2;
    if (H2 == NULL)
        return H1;
    if (H1->Element < H2->Element)
        return Merge1(H1, H2);
    else
        return Merge1(H2, H1);
}

void SwapChildren(PriorityQueue H)
{
    PriorityQueue Tmp;

    Tmp = H->Left;
    H->Left = H->Right;
    H->Right = Tmp;
}

static PriorityQueue Merge1(PriorityQueue H1, PriorityQueue H2)
{
    if (H1->Left == NULL)  /* Single node */
        H1->Left = H2;
    else
    {
        H1->Right = Merge(H1->Right, H2);
        SwapChildren(H1);
    }
    return H1;
}

PriorityQueue Insert1(ElementType X, PriorityQueue H)
{
    PriorityQueue SingleNode;

    SingleNode = malloc(sizeof(struct TreeNode));
    if (SingleNode == NULL)
        FatalError("Out of space!!!");
    else
    {
        SingleNode->Element = X; //SingleNode->Npl = 0;
        SingleNode->Left = SingleNode->Right = NULL;
        H = Merge(SingleNode, H);
    }
    return H;
}

/* DeleteMin1 returns the new tree; */
/* To get the minimum, use FindMin */
/* This is for convenience */
PriorityQueue DeleteMin1(PriorityQueue H)
{
    PriorityQueue LeftHeap, RightHeap;

    if (IsEmpty(H))
    {
        Error("Priority queue is empty");
        return H;
    }

    LeftHeap = H->Left;
    RightHeap = H->Right;
    free(H);
    return Merge(LeftHeap, RightHeap);
}

ElementType FindMin(PriorityQueue H)
{
    if (!IsEmpty(H))
        return H->Element;
    Error("Priority Queue is Empty");
    return  0;
}

int IsEmpty(PriorityQueue H)
{
    return H == NULL;
}

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

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

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

void LevelorderTraversal(PriorityQueue H)
{
    Queue Q;
    PriorityQueue TmpCell;

    if (H == NULL)
        return;

    Q = CreateQueue(1000);
    Enqueue(H, 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 "skewheap.h"
#include "queue.h"
#include "fatal.h"
#include <stdlib.h>

#define MinQueueSize ( 5 )

struct QueueRecord
{
    int Capacity;
    int Front;
    int Rear;
    int Size;
    PriorityQueue *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(PriorityQueue) * 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(PriorityQueue X, Queue Q)
{
    if (IsFullQueue(Q))
        Error("Full queue");
    else
    {
        Q->Size++;
        Q->Rear = Succ(Q->Rear, Q);
        Q->Array[Q->Rear] = X;
    }
}

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

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

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

testskew.c

#include "skewheap.h"
#include <stdio.h>

#define MaxSize 32

int main()
{
    PriorityQueue H;
    int i, j, MinElement;

    H = Initialize();
    for (i = 0, j = MaxSize / 2; i < MaxSize; i++, j = (j + 17) % MaxSize)
    {
        Insert(j, H);
        printf("Insert %d", j);
        printf("\n先序遍历:\n");
        PreorderTraversal(H);
        printf("\n中序遍历:\n");
        InorderTraversal(H);
        printf("\n后序遍历:\n");
        PostorderTraversal(H);
        printf("\n层序遍历:\n");
        LevelorderTraversal(H);
        printf("\n\n");
    }
    
    j = 0;
    while (!IsEmpty(H))
    {
        if (DeleteMin(H) != j++)
            printf("Error in DeleteMin, %d\n", j);
        printf("DeleteMin %d 之后,执行左右子树Merge", j - 1);
        printf("\n先序遍历:\n");
        PreorderTraversal(H);
        printf("\n中序遍历:\n");
        InorderTraversal(H);
        printf("\n后序遍历:\n");
        PostorderTraversal(H);
        printf("\n层序遍历:\n");
        LevelorderTraversal(H);
        printf("\n\n");
    }
    printf("Done...\n");
    return 0;
}
posted @ 2017-02-09 01:43  typewriter  阅读(534)  评论(0编辑  收藏  举报