Fibonacci Heap
Fibonacci Heap
A fibonacci heap is a data structure that consists of a collection of trees which follow min
heap or max heap property. We have already discussed min heap and max heap property in
the Heap Data Structure article. These two properties are the characteristics of the trees
present on a fibonacci heap.
In a fibonacci heap, a node can have more than two children or no children at all. Also, it has
more efficient heap operations than that supported by the binomial and binary heaps.
The fibonacci heap is called a fibonacci heap because the trees are constructed in a way such
that a tree of order n has at least Fn+2 nodes in it, where Fn+2 is the (n + 2)th Fibonacci number.
Fibonacci
Heap
Fibonacci Heap
2. Delete the min node, add all its child nodes to the root list and set the min-pointer to
the next root in the root list.
Create an array
4. Here, 23 and 7 have the same degrees, so unite them.
Unit
e those having the same degrees
5. Again, 7 and 17 have the same degrees, so unite them as well.
Unit
e those having the same degrees
6. Again 7 and 24 have the same degree, so unite them.
Uni
te those having the same degrees
7. Map the next nodes.
Ma
p the remaining nodes
8. Again, 52 and 21 have the same degree, so unite them
Unite those
having the same degrees
9. Similarly, unite 21 and 18.
Unite those
having the same degrees
10. Map the remaining root.
Map the
remaining nodes
11. The final heap is.
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
FIB_HEAP *make_fib_heap();
void insertion(FIB_HEAP *H, NODE *new, int val);
NODE *extract_min(FIB_HEAP *H);
void consolidate(FIB_HEAP *H);
void fib_heap_link(FIB_HEAP *H, NODE *y, NODE *x);
NODE *find_min_node(FIB_HEAP *H);
void decrease_key(FIB_HEAP *H, NODE *node, int key);
void cut(FIB_HEAP *H, NODE *node_to_be_decrease, NODE *parent_node);
void cascading_cut(FIB_HEAP *H, NODE *parent_node);
void Delete_Node(FIB_HEAP *H, int dec_key);
FIB_HEAP *make_fib_heap() {
FIB_HEAP *H;
H = (FIB_HEAP *)malloc(sizeof(FIB_HEAP));
H->n = 0;
H->min = NULL;
H->phi = 0;
H->degree = 0;
return H;
}
// Inserting nodes
void insertion(FIB_HEAP *H, NODE *new, int val) {
new = (NODE *)malloc(sizeof(NODE));
new->key = val;
new->degree = 0;
new->mark = false;
new->parent = NULL;
new->child = NULL;
new->visited = false;
new->left_sibling = new;
new->right_sibling = new;
if (H->min == NULL) {
H->min = new;
} else {
H->min->left_sibling->right_sibling = new;
new->right_sibling = H->min;
new->left_sibling = H->min->left_sibling;
H->min->left_sibling = new;
if (new->key < H->min->key) {
H->min = new;
}
}
(H->n)++;
}
// Union operation
FIB_HEAP *unionHeap(FIB_HEAP *H1, FIB_HEAP *H2) {
FIB_HEAP *Hnew;
Hnew = make_fib_heap();
Hnew->min = H1->min;
Hnew->min->right_sibling->left_sibling = H2->min->left_sibling;
Hnew->min->right_sibling = H2->min;
H2->min->left_sibling = Hnew->min;
temp2->right_sibling = temp1;
// Consolidate function
void consolidate(FIB_HEAP *H) {
int degree, i, d;
degree = cal_degree(H->n);
NODE *A[degree], *x, *y, *z;
for (i = 0; i <= degree; i++) {
A[i] = NULL;
}
x = H->min;
do {
d = x->degree;
while (A[d] != NULL) {
y = A[d];
if (x->key > y->key) {
NODE *exchange_help;
exchange_help = x;
x = y;
y = exchange_help;
}
if (y == H->min)
H->min = x;
fib_heap_link(H, y, x);
if (y->right_sibling == x)
H->min = x;
A[d] = NULL;
d++;
}
A[d] = x;
x = x->right_sibling;
} while (x != H->min);
H->min = NULL;
for (i = 0; i < degree; i++) {
if (A[i] != NULL) {
A[i]->left_sibling = A[i];
A[i]->right_sibling = A[i];
if (H->min == NULL) {
H->min = A[i];
} else {
H->min->left_sibling->right_sibling = A[i];
A[i]->right_sibling = H->min;
A[i]->left_sibling = H->min->left_sibling;
H->min->left_sibling = A[i];
if (A[i]->key < H->min->key) {
H->min = A[i];
}
}
if (H->min == NULL) {
H->min = A[i];
} else if (A[i]->key < H->min->key) {
H->min = A[i];
}
}
}
}
// Linking
void fib_heap_link(FIB_HEAP *H, NODE *y, NODE *x) {
y->right_sibling->left_sibling = y->left_sibling;
y->left_sibling->right_sibling = y->right_sibling;
if (x->right_sibling == x)
H->min = x;
y->left_sibling = y;
y->right_sibling = y;
y->parent = x;
if (x->child == NULL) {
x->child = y;
}
y->right_sibling = x->child;
y->left_sibling = x->child->left_sibling;
x->child->left_sibling->right_sibling = y;
x->child->left_sibling = y;
if ((y->key) < (x->child->key))
x->child = y;
(x->degree)++;
}
// Extract min
NODE *extract_min(FIB_HEAP *H) {
if (H->min == NULL)
printf("\n The heap is empty");
else {
NODE *temp = H->min;
NODE *pntr;
pntr = temp;
NODE *x = NULL;
if (temp->child != NULL) {
x = temp->child;
do {
pntr = x->right_sibling;
(H->min->left_sibling)->right_sibling = x;
x->right_sibling = H->min;
x->left_sibling = H->min->left_sibling;
H->min->left_sibling = x;
if (x->key < H->min->key)
H->min = x;
x->parent = NULL;
x = pntr;
} while (pntr != temp->child);
}
(temp->left_sibling)->right_sibling = temp->right_sibling;
(temp->right_sibling)->left_sibling = temp->left_sibling;
H->min = temp->right_sibling;
if (temp == temp->right_sibling && temp->child == NULL)
H->min = NULL;
else {
H->min = temp->right_sibling;
consolidate(H);
}
H->n = H->n - 1;
return temp;
}
return H->min;
}
if (node_to_be_decrease == node_to_be_decrease->right_sibling)
parent_node->child = NULL;
node_to_be_decrease->left_sibling->right_sibling = node_to_be_decrease->right_sibling;
node_to_be_decrease->right_sibling->left_sibling = node_to_be_decrease->left_sibling;
if (node_to_be_decrease == parent_node->child)
parent_node->child = node_to_be_decrease->right_sibling;
(parent_node->degree)--;
node_to_be_decrease->left_sibling = node_to_be_decrease;
node_to_be_decrease->right_sibling = node_to_be_decrease;
H->min->left_sibling->right_sibling = node_to_be_decrease;
node_to_be_decrease->right_sibling = H->min;
node_to_be_decrease->left_sibling = H->min->left_sibling;
H->min->left_sibling = node_to_be_decrease;
node_to_be_decrease->parent = NULL;
node_to_be_decrease->mark = false;
}
else {
if (node_to_be_decrease->key < new_key) {
printf("\n Invalid new key for decrease key operation \n ");
} else {
node_to_be_decrease->key = new_key;
parent_node = node_to_be_decrease->parent;
if ((parent_node != NULL) && (node_to_be_decrease->key < parent_node->key)) {
printf("\n cut called");
cut(H, node_to_be_decrease, parent_node);
printf("\n cascading cut called");
cascading_cut(H, parent_node);
}
if (node_to_be_decrease->key < H->min->key) {
H->min = node_to_be_decrease;
}
}
}
}
find_use->visited = false;
}
FIB_HEAP *insertion_procedure() {
FIB_HEAP *temp;
int no_of_nodes, ele, i;
NODE *new_node;
temp = (FIB_HEAP *)malloc(sizeof(FIB_HEAP));
temp = NULL;
if (temp == NULL) {
temp = make_fib_heap();
}
printf(" \n enter number of nodes to be insert = ");
scanf("%d", &no_of_nodes);
for (i = 1; i <= no_of_nodes; i++) {
printf("\n node %d and its key value = ", i);
scanf("%d", &ele);
insertion(temp, new_node, ele);
}
return temp;
}
void Delete_Node(FIB_HEAP *H, int dec_key) {
NODE *p = NULL;
find_node(H, H->min, dec_key, -5000);
p = extract_min(H);
if (p != NULL)
printf("\n Node deleted");
else
printf("\n Node not deleted:some error");
}
switch (operation_no) {
case 1:
heap = make_fib_heap();
break;
case 2:
if (heap == NULL) {
heap = make_fib_heap();
}
printf(" enter number of nodes to be insert = ");
scanf("%d", &no_of_nodes);
for (i = 1; i <= no_of_nodes; i++) {
printf("\n node %d and its key value = ", i);
scanf("%d", &ele);
insertion(heap, new_node, ele);
}
break;
case 3:
min_node = find_min_node(heap);
if (min_node == NULL)
printf("No minimum value");
else
printf("\n min value = %d", min_node->key);
break;
case 4:
if (heap == NULL) {
printf("\n no FIbonacci heap created \n ");
break;
}
h1 = insertion_procedure();
heap = unionHeap(heap, h1);
printf("Unified Heap:\n");
print_heap(heap->min);
break;
case 5:
if (heap == NULL)
printf("Empty Fibonacci heap");
else {
extracted_min = extract_min(heap);
printf("\n min value = %d", extracted_min->key);
printf("\n Updated heap: \n");
print_heap(heap->min);
}
break;
case 6:
if (heap == NULL)
printf("Fibonacci heap is empty");
else {
printf(" \n node to be decreased = ");
scanf("%d", &dec_key);
printf(" \n enter the new key = ");
scanf("%d", &new_key);
find_use = heap->min;
find_node(heap, find_use, dec_key, new_key);
printf("\n Key decreased- Corresponding heap:\n");
print_heap(heap->min);
}
break;
case 7:
if (heap == NULL)
printf("Fibonacci heap is empty");
else {
printf(" \n Enter node key to be deleted = ");
scanf("%d", &dec_key);
Delete_Node(heap, dec_key);
printf("\n Node Deleted- Corresponding heap:\n");
print_heap(heap->min);
break;
}
case 8:
print_heap(heap->min);
break;
case 9:
free(new_node);
free(heap);
exit(0);
default:
printf("Invalid choice ");
}
}
}