13. 左式堆(left heap)
fatal.h
#include <stdio.h>
#include <stdlib.h>
#define Error(Str) FatalError(Str)
#define FatalError(Str) fprintf(stderr, "%s\n", Str), exit(1)
leftheap.h
typedef int ElementType;
#ifndef _LeftHeap_H
#define _LeftHeap_H
struct TreeNode;
typedef struct TreeNode *PriorityQueue;
/* Minimal set of priority queue operations */
/* Note that nodes will be shared among several */
/* leftist heaps after a merge; the user must */
/* make sure to not use the old leftist heaps */
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
leftheap.c
#include "leftheap.h"
#include "queue.h"
#include "fatal.h"
#include <stdlib.h>
struct TreeNode
{
ElementType Element;
PriorityQueue Left;
PriorityQueue Right;
int Npl;
};
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; /* H1->Right is already NULL,
H1->Npl is already 0 */
else
{
H1->Right = Merge(H1->Right, H2);
if (H1->Left->Npl < H1->Right->Npl)
SwapChildren(H1);
H1->Npl = H1->Right->Npl + 1;
}
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(80);
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 "leftheap.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;
}
testleft.c
#include "leftheap.h"
#include <stdio.h>
#define MaxSize 10
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;
}