算法导论 斐波那契堆

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct FIBNode
{
	FIBNode *p;
	FIBNode *child;
	FIBNode *left;
	FIBNode *right;
	int key;
	int degree;
	bool mark;
}FNode,*pFNode;

typedef struct FIBTree
{
	pFNode min;
	int n;
}FIB,*pFIB;

pFIB make_FIB_heap()
{
	pFIB h=(pFIB)malloc(sizeof(FIB));
	h->min=NULL;
	h->n=0;
	return h;
}

void FIB_heap_insert(pFIB h,pFNode x)
{
	x->degree=0;
	x->p=NULL;
	x->child=NULL;
	x->mark=false;
	if(h->min==NULL)
	{
		x->left=x->right=x;
		h->min=x;
	}
	else
	{
		pFNode l=h->min->left;
		x->right=h->min;
		x->left=l;
		l->right=x;
		h->min->left=x;	
		if(x->key<h->min->key)
			h->min=x;
	}
	h->n++;
}

pFIB FIB_heap_union(pFIB h1,pFIB h2)
{
	pFIB h=make_FIB_heap();
	h->min=h1->min;
	if(h->min != NULL && h2->min != NULL)
	{
		pFNode x=h->min->right,y=h2->min->left;
		h->min->right=h2->min;
		h2->min->left=h->min;
		x->left=y;
		y->right=x;
	}
	if(h1->min==NULL || (h2->min !=NULL && h2->min->key<h1->min->key))
	{
		h->min=h2->min;
	}
	h->n=h1->n+h2->n;
	return h;
}

void FIB_heap_link(pFIB h,pFNode y,pFNode x)
{
	y->left->right=y->right;
	y->right->left=y->left;
	pFNode k=x->child;
	if(k == NULL)
	{
		x->child=y;
		y->left=y->right=y;		
	}
	else
	{
		pFNode l=k->left;
		l->right=y;
		y->left=l;
		k->left=y;
		y->right=k;
	}
	x->degree++;
	y->p=x;
	y->mark=false;
}

void consolidate(pFIB h)
{
	int Dn=(log((double)h->n)/log(2.0));
	pFNode *A=(pFNode*)malloc((Dn+1)*sizeof(pFNode));
	for(int i=0;i<=Dn;i++)
		A[i]=NULL;
	pFNode x=h->min,k;
	bool stopFlag=false;
	if(x!=NULL)
	{		
		while(!stopFlag)
		{
			if(x==x->right || A[x->right->degree]==x->right)
				stopFlag=true;
			k=x->right;
			int d=x->degree;
			while(A[d]!=NULL)
			{
				pFNode y=A[d];
				if(y->key<x->key)
				{
					pFNode temp=x;
					x=y;
					y=temp;
				}
				FIB_heap_link(h,y,x);
				A[d]=NULL;
				d++;
			}
			A[d]=x;
			x=k;
		}
	}
	h->min=NULL;
	for(int i=0;i<=Dn;i++)
	{
		if(A[i] != NULL)
		{
			if(h->min==NULL)
			{
				h->min=A[i];
				A[i]->left=A[i]->right=A[i];
			}
			else
			{
				pFNode l=h->min->left;
				h->min->left=A[i];
				A[i]->right=h->min;
				l->right=A[i];
				A[i]->left=l;
				if(A[i]->key<h->min->key)
					h->min=A[i];
			}
		}
	}
}

pFNode FIB_heap_extract_min(pFIB h)
{
	pFNode z=h->min;
	if(z != NULL)
	{
		pFNode x=z->child,k;
		if(x!=NULL)
		{
			for(int i=0;i<z->degree;i++)
			{
				x->left->right=x->right;
				x->right->left=x->left;
				k=x->right;
				pFNode y=z->left;
				z->left=x;
				x->right=z;
				y->right=x;
				x->left=y;
				x=k;
			}
		}
		z->left->right=z->right;
		z->right->left=z->left;
		if(z==z->right)
			h->min=NULL;
		else
		{
			h->min=z->right;
			consolidate(h);
		}
		h->n--;
	}
	return z;
}

pFNode createNode(int key)
{
	pFNode n=(pFNode)malloc(sizeof(FNode));
	n->degree=0;
	n->p=n->child=n->left=n->right=NULL;
	n->mark=false;
	n->key=key;
	return n;
}

void initHeap(pFIB h)
{
	pFNode n23=createNode(23);
	pFNode n7=createNode(7);
	pFNode n3=createNode(3);
	pFNode n17=createNode(17);
	pFNode n24=createNode(24);
	pFNode n18=createNode(18);
	pFNode n52=createNode(52);
	pFNode n38=createNode(38);
	pFNode n30=createNode(30);
	pFNode n26=createNode(26);
	pFNode n46=createNode(46);
	pFNode n39=createNode(39);
	pFNode n41=createNode(41);
	pFNode n35=createNode(35);
	h->min=n3;
	h->n=14;
	n3->left=n7;
	n3->right=n17;
	n3->child=n18;
	n3->degree=3;

	n7->left=n23;
	n7->right=n3;
	
	n23->left=n24;
	n23->right=n7;

	n17->left=n3;
	n17->right=n24;
	n17->child=n30;
	n17->degree=1;

	n24->left=n17;
	n24->right=n23;
	n24->child=n26;
	n24->degree=2;

	n18->left=n38;
	n18->right=n52;
	n18->child=n39;
	n18->degree=1;
	n18->p=n3;
	n18->mark=true;

	n52->left=n18;
	n52->right=n38;
	n52->p=n3;

	n38->left=n52;
	n38->right=n18;
	n38->child=n41;
	n38->degree=1;
	n38->p=n3;

	n30->p=n17;
	n30->left=n30->right=n30;

	n26->left=n46;
	n26->right=n46;
	n26->child=n35;
	n26->degree=1;
	n26->p=n24;
	n26->mark=true;

	n46->left=n26;
	n46->right=n26;
	n46->p=n24;

	n39->p=n18;
	n39->left=n39->right=n39;
	n39->mark=true;

	n41->p=n38;
	n41->left=n41->right=n41;

	n35->p=n26;
	n35->left=n35->right=n35;
}

void printList(pFNode n)
{
	pFNode x=n;
	if(x)
	{
		do
		{
			printf("%d ",x->key);
			x=x->right;
		}while(x != n);
	}
	printf("\n");
}

void cut(pFIB h,pFNode x,pFNode y)
{
	y->child=x->right;
	x->left->right=x->right;
	x->right->left=x->left;
	if(y->degree==1)
		y->child=NULL;
	y->degree--;

	pFNode z=h->min->left;
	h->min->left=x;
	x->right=h->min;
	z->right=x;
	x->left=z;

	x->p=NULL;
	x->mark=false;
}

void cascading_cut(pFIB h,pFNode y)
{
	pFNode z=y->p;
	if(z != NULL)
	{
		if(y->mark==false)
			y->mark=true;
		else
		{
			cut(h,y,z);
			cascading_cut(h,z);
		}
	}
}

void FIB_heap_decreaseKey(pFIB h,pFNode x,int k)
{
	if(k>x->key)
	{
		printf("new key is greater than current key");
		return;
	}
	x->key=k;
	pFNode y=x->p;
	if(y!=NULL && x->key<y->key)
	{
		cut(h,x,y);
		cascading_cut(h,y);
	}
	if(x->key<h->min->key)
		h->min=x;
}

void main()
{
	pFIB h=make_FIB_heap();
	initHeap(h);
	pFNode x=createNode(21);
	FIB_heap_insert(h,x);
	printList(h->min);
	pFNode z=FIB_heap_extract_min(h);
	printf("%d\n",z->key);
	printList(h->min);
	x=h->min->child->left->child->left;
	FIB_heap_decreaseKey(h,x,15);
	printList(h->min);
	x=h->min->child->left->child->child;
	FIB_heap_decreaseKey(h,x,5);
	printList(h->min);
	getchar();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值