#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<cmath>
#include<climits>
using namespace std;
struct FibonacciHeapNode
{
int key;
int degree;
FibonacciHeapNode * left;
FibonacciHeapNode * right;
FibonacciHeapNode * parent;
FibonacciHeapNode * child;
bool marked;
};
typedef FibonacciHeapNode FibNode;
struct FibonacciHeap
{
int keyNum;
FibonacciHeapNode * min;
int maxNumOfDegree;
FibonacciHeapNode ** cons;
};
typedef FibonacciHeap FibHeap;
inline void FibNodeRemove(FibNode * x);
void FibNodeAdd(FibNode * x, FibNode * y);
FibHeap * FibHeapMake() ;
FibNode * FibHeapNodeMake();
void FibHeapInsert(FibHeap * heap, FibNode * x);
void FibHeapInsertKeys(FibHeap * heap, int keys[], int keyNum);
static void FibHeapInsertKey(FibHeap * heap, int key);
FibNode * FibHeapExtractMin(FibHeap * heap);
void FibHeapConsolidate(FibHeap * heap);
void FibHeapLink(FibHeap * heap, FibNode * x, FibNode *y);
static void FibHeapConsMake(FibHeap * heap);
static FibNode *FibHeapMinRemove(FibHeap * heap);
void FibHeapDecrease(FibHeap * heap, FibNode * x, int key);
static void FibHeapCut(FibHeap * heap, FibNode * x, FibNode * y);
static void FibHeapCascadingCut(FibHeap * heap, FibNode * y);
void renewDegree(FibNode * parent, int degree);
void FibHeapDelete(FibHeap * heap, FibNode * x);
FibNode * FibHeapSearch(FibHeap * heap, int key);
static FibNode * FibNodeSearch(FibNode * x, int key);
void FibHeapDestory(FibHeap * heap);
static void FibNodeDestory(FibNode * x);
static void FibHeapPrint(FibHeap * heap);
static void FibNodePrint(FibNode * x);
inline void FibNodeRemove(FibNode * x)
{
x->left->right = x->right;
x->right->left = x->left;
}
inline void FibNodeAdd(FibNode * x, FibNode * y)
{
x->left = y->left;
y->left->right = x;
x->right = y;
y->left = x;
}
FibHeap * FibHeapMake()
{
FibHeap *heap=NULL;
heap=(FibHeap*)malloc(sizeof(FibHeap));
if(NULL == heap)
{
puts("out of space");
exit(1);
}
memset(heap,0,sizeof(FibHeap));
return heap;
}
FibNode * FibHeapNodeMake()
{
FibNode *node=NULL;
node=(FibNode*)malloc(sizeof(FibNode));
if(NULL == node)
{
puts("out of space!");
exit(1);
}
memset(node,0,sizeof(FibNode));
node->left = node->right = node;
return node;
}
void FibHeapInsert(FibHeap * heap, FibNode * x)
{
if (0 == heap->keyNum)
{
heap->min = x;
}
else
{
FibNodeAdd(x, heap->min);
x->parent = NULL;
if (x->key < heap->min->key)
{
heap->min = x;
}
}
heap->keyNum++;
}
void FibHeapInsertKeys(FibHeap * heap, int keys[], int keyNum)
{
for (int i = 0; i < keyNum; i++)
{
FibHeapInsertKey(heap, keys[i]);
}
}
static void FibHeapInsertKey(FibHeap * heap, int key)
{
FibNode * x = NULL;
x = FibHeapNodeMake();
x->key = key;
FibHeapInsert(heap, x);
}
FibNode * FibHeapExtractMin(FibHeap * heap)
{
FibNode * x = NULL, * z = heap->min;
if (z != NULL)
{
while (NULL != z->child)
{
x = z->child;
FibNodeRemove(x);
if (x->right == x)
{
z->child = NULL;
}
else
{
z->child = x->right;
}
FibNodeAdd(x, z);
x->parent = NULL;
}
FibNodeRemove(z);
if (z->right == z)
{
heap->min = NULL;
}
else
{
heap->min = z->right;
FibHeapConsolidate(heap);
}
heap->keyNum--;
}
return z;
}
void FibHeapConsolidate(FibHeap * heap)
{
int D, d;
FibNode * w = heap->min,
* x = NULL,
* y = NULL;
FibHeapConsMake(heap);
D = heap->maxNumOfDegree + 1;
for (int i = 0; i < D; i++)
{
heap->cons[i] = NULL;
}
while (NULL != heap->min)
{
x = FibHeapMinRemove(heap);
d = x->degree;
while (NULL != heap->cons[d])
{
y = heap->cons[d];
if (x->key > y->key)
{
swap(x, y);
}
FibHeapLink(heap, y, x);
heap->cons[d] = NULL;
d++;
}
heap->cons[d] = x;
}
heap->min = NULL;
for (int i = 0; i < D; i++)
{
if (heap->cons[i] != NULL)
{
if (NULL == heap->min)
{
heap->min = heap->cons[i];
}
else
{
FibNodeAdd(*(heap->cons + i), heap->min);
if ((*(heap->cons + i))->key < heap->min->key)
{
heap->min = *(heap->cons + i);
}
}
}
}
}
void FibHeapLink(FibHeap * heap, FibNode * x, FibNode *y)
{
FibNodeRemove(x);
if (NULL == y->child)
{
y->child = x;
}
else
{
FibNodeAdd(x, y->child);
}
x->parent = y;
y->degree++;
x->marked = false;
}
static void FibHeapConsMake(FibHeap * heap)
{
int old = heap->maxNumOfDegree;
heap->maxNumOfDegree = int(log(heap->keyNum * 1.0) / log(2.0)) + 1;
if (old < heap->maxNumOfDegree)
{
heap->cons = (FibNode **) realloc(heap->cons,
sizeof(FibHeap *) * (heap->maxNumOfDegree + 1));
if (NULL == heap->cons)
{
puts("Out of Space!");
exit(1);
}
}
}
static FibNode *FibHeapMinRemove(FibHeap * heap)
{
FibNode *minx = heap->min;
if (heap->min == minx->right)
{
heap->min = NULL;
}
else
{
FibNodeRemove(minx);
heap->min = minx->right;
}
minx->left = minx->right = minx;
return minx;
}
void FibHeapDecrease(FibHeap * heap, FibNode * x, int key)
{
FibNode * y = x->parent;
if (x->key < key)
{
puts("new key is greater than current key!");
exit(1);
}
x->key = key;
if (NULL != y && x->key < y->key)
{
FibHeapCut(heap, x, y);
FibHeapCascadingCut(heap, y);
}
if (x->key < heap->min->key)
{
heap->min = x;
}
}
static void FibHeapCut(FibHeap * heap, FibNode * x, FibNode * y)
{
FibNodeRemove(x);
renewDegree(y, x->degree);
if (x == x->right)
{
y->child = NULL;
}
else
{
y->child = x->right;
}
x->parent = NULL;
x->left = x->right = x;
x->marked = false;
FibNodeAdd(x, heap->min);
}
static void FibHeapCascadingCut(FibHeap * heap, FibNode * y)
{
FibNode * z = y->parent;
if (NULL != z)
{
if (y->marked == false)
{
y->marked = true;
}
else
{
FibHeapCut(heap, y, z);
FibHeapCascadingCut(heap, z);
}
}
}
void renewDegree(FibNode * parent, int degree)
{
parent->degree -= degree;
if (parent-> parent != NULL)
{
renewDegree(parent->parent, degree);
}
}
void FibHeapDelete(FibHeap * heap, FibNode * x)
{
FibHeapDecrease(heap, x, INT_MIN);
FibHeapExtractMin(heap);
}
FibNode * FibHeapSearch(FibHeap * heap, int key)
{
return FibNodeSearch(heap->min, key);
}
static FibNode * FibNodeSearch(FibNode * x, int key)
{
FibNode * w = x, * y = NULL;
if (x != NULL)
{
do
{
if (w->key == key)
{
y = w;
break;
}
else if (NULL != (y = FibNodeSearch(w->child, key)))
{
break;
}
w = w->right;
}
while (w != x);
}
return y;
}
void FibHeapDestory(FibHeap * heap)
{
FibNodeDestory(heap->min);
free(heap);
heap = NULL;
}
static void FibNodeDestory(FibNode * x)
{
FibNode * p = x, *q = NULL;
while (p != NULL)
{
FibNodeDestory(p->child);
q = p;
if (p -> left == x)
{
p = NULL;
}
else
{
p = p->left;
}
free(q->right);
}
}
static void FibHeapPrint(FibHeap * heap)
{
printf("The keyNum = %d\nThe sequence of printing is: Heap->min , its children if ever and then its left\n", heap->keyNum);
FibNodePrint(heap->min);
puts("\n");
};
static void FibNodePrint(FibNode * x)
{
FibNode * p = NULL;
if (NULL == x)
{
return ;
}
p = x;
do
{
printf(" (");
printf("%d", p->key);
if (p->child != NULL)
{
FibNodePrint(p->child);
}
printf(") ");
p = p->left;
}
while (x != p);
}
int keys[10] = {1, 2, 3, 4, 5, 6, 7, 9, 10, 11};
int main()
{
FibHeap * heap = NULL;
FibNode * x = NULL;
heap = FibHeapMake();
FibHeapInsertKeys(heap, keys, 10);
FibHeapPrint(heap);
x = FibHeapExtractMin(heap);
printf("抽取最小值%d之后:\n", x->key);
FibHeapPrint(heap);
x = FibHeapSearch(heap, 11);
if (NULL != x)
{
printf("查找%d成功,", x->key);
FibHeapDecrease(heap, x, 8);
printf("减小到%d后:\n", x->key);
FibHeapPrint(heap);
}
x = FibHeapSearch(heap, 6);
if (NULL != x)
{
printf("查找%d成功,", x->key);
FibHeapDecrease(heap, x, 1);
printf("减小到%d后:\n", x->key);
FibHeapPrint(heap);
}
x = FibHeapSearch(heap, 7);
if (NULL != x)
{
printf("删除%d成功:\n", x->key);
FibHeapDelete(heap, x);
FibHeapPrint(heap);
}
FibHeapDestory(heap);
return 0;
}