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


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值