您的位置:首页 > 理论基础 > 数据结构算法

C源码@数据结构与算法->BinomialQueue

2015-08-24 20:00 701 查看
/*
* fatal.h
*/
#include
#include

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

/*
* testbin.cpp
*/
#include
#include "binomial.h"

#define MaxSize (12000)

int main()
{
BinQueue H;
int i, j;
ElementType AnItem;

H = Initialize();
for (i = 0, j = MaxSize / 2; i < MaxSize; ++i, j = (j + 71) % MaxSize)
{
H = Insert(j, H);
}

j = 0;
while (!IsEmpty(H))
{
if (DeleteMin(H) != j++)
{
printf("Error in DeleteMin, %d\n", j);
}
}

if (j != MaxSize)
{
printf("Error in counting!\n");
}

printf("Done...\n");

return 0;
}


/*
* binomial.h
*/
#ifndef _BINQUEUE_H
#define _BINQUEUE_H

#ifndef NULL
#define NULL (0)
#endif

typedef long ElementType;
#define Infinity (30000L)

#define MaxTrees (14)	/* Stores 2^14 - 1 items */
#define Capacity (16383)

struct BinNode;
typedef struct BinNode *BinTree;
struct Collection;
typedef struct Collection *BinQueue;

#ifdef __cplusplus
extern "C" {
#endif

BinQueue Initialize();
void Destroy(BinQueue H);
BinQueue MakeEmpty(BinQueue H);
BinQueue Insert(ElementType Item, BinQueue H);
BinQueue Merge(BinQueue H1, BinQueue H2);
int IsEmpty(BinQueue H);
int IsFull(BinQueue H);
ElementType FindMin(BinQueue H);
ElementType DeleteMin(BinQueue H);

#ifdef __cplusplus
}
#endif

#endif /* _BINQUEUE_H */

/*
* binomial.cpp
*/
#include
#include "fatal.h"
#include "binomial.h"

typedef struct BinNode *Position;

struct BinNode
{
ElementType Element;
Position LeftChild;
Position NextSibling;
};

struct Collection
{
int CurrentSize;
BinTree TheTrees[MaxTrees];
};

BinQueue Initialize()
{
BinQueue H;
int i;

H = (BinQueue)malloc(sizeof(struct Collection));
if (H == NULL)
{
FatalError("Out of space!");
}
H->CurrentSize = 0;
for (i = 0; i < MaxTrees; ++i)
{
H->TheTrees[i] = NULL;
}

return H;
}

static void DestroyTree(BinTree T)
{
if (T != NULL)
{
DestroyTree(T->LeftChild);
DestroyTree(T->NextSibling);
free(T);
}
}

void Destroy(BinQueue H)
{
int i;

for (i = 0; i < MaxTrees; ++i)
{
DestroyTree(H->TheTrees[i]);
}
}

BinQueue MakeEmpty(BinQueue H)
{
int i;

Destroy(H);
for (i = 0; i < MaxTrees; ++i)
{
H->TheTrees[i] = NULL;
}

return H;
}

BinQueue Insert(ElementType Item, BinQueue H)
{
BinTree NewNode;
BinQueue OneItem;

NewNode = (BinTree)malloc(sizeof(struct BinNode));
if (NewNode == NULL)
{
FatalError("Out of space!");
}
NewNode->LeftChild = NULL;
NewNode->NextSibling = NULL;
NewNode->Element = Item;

OneItem = Initialize();
OneItem->CurrentSize = 1;
OneItem->TheTrees[0] = NewNode;

return Merge(H, OneItem);
}

BinTree CombineTrees(BinTree T1, BinTree T2)
{
if (T1->Element > T2->Element)
{
return CombineTrees(T2, T1);
}
T2->NextSibling = T1->LeftChild;
T1->LeftChild = T2;

return T1;
}

BinQueue Merge(BinQueue H1, BinQueue H2)
{
BinTree T1, T2, Carry = NULL;
int i, j;

if (H1->CurrentSize + H2->CurrentSize > Capacity)
{
FatalError("Merge would exceed capacity!");
}

H1->CurrentSize += H2->CurrentSize;
for (i = 0, j = 1; j <= H1->CurrentSize; ++i, j *= 2)
{
T1 = H1->TheTrees[i];
T2 = H2->TheTrees[i];

switch (!!T1 + 2 * !!T2 + 4 * !!Carry)
{
case 0: /* No trees */
case 1: /* Only H1 */
break;
case 2: /* Only H2 */
H1->TheTrees[i] = T2;
H2->TheTrees[i] = NULL;
break;
case 4: /* Only Carry */
H1->TheTrees[i] = Carry;
Carry = NULL;
break;
case 3: /* H1 and H2 */
Carry = CombineTrees(T1, T2);
H1->TheTrees[i] = NULL;
H2->TheTrees[i] = NULL;
break;
case 5:	/* H1 and Carry */
Carry = CombineTrees(T1, Carry);
H1->TheTrees[i] = NULL;
break;
case 6:	/* H2 and Carry */
Carry = CombineTrees(T2, Carry);
H2->TheTrees[i] = NULL;
break;
case 7:	/* All threes */
H1->TheTrees[i] = Carry;
Carry = CombineTrees(T1, T2);
H2->TheTrees[i] = NULL;
break;
}
}

return H1;
}

int IsEmpty(BinQueue H)
{
return H->CurrentSize == 0;
}

int IsFull(BinQueue H)
{
return H->CurrentSize == Capacity;
}

ElementType FindMin(BinQueue H)
{
int i;
ElementType MinItem;

if (IsEmpty(H))
{
FatalError("Empty binomial queue!");
}

MinItem = Infinity;
for (i = 0; i < MaxTrees; ++i)
{
if (H->TheTrees[i]
&& H->TheTrees[i]->Element < MinItem)
{
MinItem = H->TheTrees[i]->Element < MinItem;
}
}

return MinItem;
}

ElementType DeleteMin(BinQueue H)
{
int i, j;
int MinTree;	/* The tree with the minimum item */
BinQueue DeletedQueue;
Position DeletedTree, OldRoot;
ElementType MinItem;

if (IsEmpty(H))
{
FatalError("Empty binomial queue!");
}

MinItem = Infinity;
for (i = 0; i < MaxTrees; ++i)
{
if (H->TheTrees[i]
&& H->TheTrees[i]->Element < MinItem)
{
/* Update minimum */
MinItem = H->TheTrees[i]->Element;
MinTree = i;
}
}

DeletedTree = H->TheTrees[MinTree];
OldRoot = DeletedTree;
DeletedTree = DeletedTree->LeftChild;
free(OldRoot);

DeletedQueue = Initialize();
DeletedQueue->CurrentSize = (1 << MinTree) - 1;
for (j = MinTree - 1; j >= 0; j--)
{
DeletedQueue->TheTrees[j] = DeletedTree;
DeletedTree = DeletedTree->NextSibling;
DeletedQueue->TheTrees[j]->NextSibling = NULL;
}

H->TheTrees[MinTree] = NULL;
H->CurrentSize -= DeletedQueue->CurrentSize + 1;

Merge(H, DeletedQueue);

return MinItem;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: