#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();
}
算法导论 斐波那契堆
最新推荐文章于 2025-06-18 20:09:51 发布