0% found this document useful (0 votes)
9 views19 pages

Fibonacci Heap

A Fibonacci heap is a data structure composed of a collection of trees that maintain min or max heap properties, allowing for more efficient operations than binomial or binary heaps. Key features include a pointer to the minimum element, marked nodes for decrease key operations, and a circular doubly linked list for child nodes. Operations such as insertion, extraction of the minimum, and union of heaps are defined, along with their respective algorithms and implementations.

Uploaded by

jpanigrahicse24
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views19 pages

Fibonacci Heap

A Fibonacci heap is a data structure composed of a collection of trees that maintain min or max heap properties, allowing for more efficient operations than binomial or binary heaps. Key features include a pointer to the minimum element, marked nodes for decrease key operations, and a circular doubly linked list for child nodes. Operations such as insertion, extraction of the minimum, and union of heaps are defined, along with their respective algorithms and implementations.

Uploaded by

jpanigrahicse24
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 19

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

Properties of a Fibonacci Heap


Important properties of a Fibonacci heap are:
1. It is a set of min heap-ordered trees. (i.e. The parent is always smaller than the
children.)
2. A pointer is maintained at the minimum element node.
3. It consists of a set of marked nodes. (Decrease key operation)
4. The trees within a Fibonacci heap are unordered but rooted.

Memory Representation of the Nodes in a Fibonacci Heap


The roots of all the trees are linked together for faster access. The child nodes of a parent
node are connected to each other through a circular doubly linked list as shown below.
There are two main advantages of using a circular doubly linked list.
1. Deleting a node from the tree takes O(1) time.
2. The concatenation of two such lists takes O(1) time.
Fibonacci Heap Structure

Operations on a Fibonacci Heap


Insertion
Algorithm
insert(H, x)
degree[x] = 0
p[x] = NIL
child[x] = NIL
left[x] = x
right[x] = x
mark[x] = FALSE
concatenate the root list containing x with root list H
if min[H] == NIL or key[x] < key[min[H]]
then min[H] = x
n[H] = n[H] + 1
Inserting a node into an already existing heap follows the steps below.
1. Create a new node for the element.
2. Check if the heap is empty.
3. If the heap is empty, set the new node as a root node and mark it min.
4. Else, insert the node into the root list and update min.
In
sertion Example
Find Min
The minimum element is always given by the min pointer.
Union
Union of two fibonacci heaps consists of following steps.
1. Concatenate the roots of both the heaps.
2. Update min by selecting a minimum key from the new root lists.
Union
of two heaps
Extract Min
It is the most important operation on a fibonacci heap. In this operation, the node with
minimum value is removed from the heap and the tree is re-adjusted.
The following steps are followed:
1. Delete the min node.
2. Set the min-pointer to the next root in the root list.
3. Create an array of size equal to the maximum degree of the trees in the heap before
deletion.
4. Do the following (steps 5-7) until there are no multiple roots with the same degree.
5. Map the degree of current root (min-pointer) to the degree in the array.
6. Map the degree of next root to the degree in array.
7. If there are more than two mappings for the same degree, then apply union operation
to those roots such that the min-heap property is maintained (i.e. the minimum is at
the root).
An implementation of the above steps can be understood in the example below.
1. We will perform an extract-min operation on the heap below.

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.

Delete the min node


3. The maximum degree in the tree is 3. Create an array of size 4 and map degree of the
next roots with the array.

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.

// Operations on a Fibonacci heap in C

#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct _NODE {


int key;
int degree;
struct _NODE *left_sibling;
struct _NODE *right_sibling;
struct _NODE *parent;
struct _NODE *child;
bool mark;
bool visited;
} NODE;

typedef struct fibanocci_heap {


int n;
NODE *min;
int phi;
int degree;
} FIB_HEAP;

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

// Printing the heap


void print_heap(NODE *n) {
NODE *x;
for (x = n;; x = x->right_sibling) {
if (x->child == NULL) {
printf("node with no child (%d) \n", x->key);
} else {
printf("NODE(%d) with child (%d)\n", x->key, x->child->key);
print_heap(x->child);
}
if (x->right_sibling == n) {
break;
}
}
}

// 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)++;
}

// Find min node


NODE *find_min_node(FIB_HEAP *H) {
if (H == NULL) {
printf(" \n Fibonacci heap not yet created \n");
return NULL;
} else
return H->min;
}

// Union operation
FIB_HEAP *unionHeap(FIB_HEAP *H1, FIB_HEAP *H2) {
FIB_HEAP *Hnew;
Hnew = make_fib_heap();
Hnew->min = H1->min;

NODE *temp1, *temp2;


temp1 = Hnew->min->right_sibling;
temp2 = H2->min->left_sibling;

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;

if ((H1->min == NULL) || (H2->min != NULL && H2->min->key < H1->min->key))


Hnew->min = H2->min;
Hnew->n = H1->n + H2->n;
return Hnew;
}

// Calculate the degree


int cal_degree(int n) {
int count = 0;
while (n > 0) {
n = n / 2;
count++;
}
return count;
}

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

void cut(FIB_HEAP *H, NODE *node_to_be_decrease, NODE *parent_node) {


NODE *temp_parent_check;

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

void cascading_cut(FIB_HEAP *H, NODE *parent_node) {


NODE *aux;
aux = parent_node->parent;
if (aux != NULL) {
if (parent_node->mark == false) {
parent_node->mark = true;
} else {
cut(H, parent_node, aux);
cascading_cut(H, aux);
}
}
}

void decrease_key(FIB_HEAP *H, NODE *node_to_be_decrease, int new_key) {


NODE *parent_node;
if (H == NULL) {
printf("\n FIbonacci heap not created ");
return;
}
if (node_to_be_decrease == NULL) {
printf("Node is not in the heap");
}

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

void *find_node(FIB_HEAP *H, NODE *n, int key, int new_key) {


NODE *find_use = n;
NODE *f = NULL;
find_use->visited = true;
if (find_use->key == key) {
find_use->visited = false;
f = find_use;
decrease_key(H, f, new_key);
}
if (find_use->child != NULL) {
find_node(H, find_use->child, key, new_key);
}
if ((find_use->right_sibling->visited != true)) {
find_node(H, find_use->right_sibling, key, new_key);
}

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");
}

int main(int argc, char **argv) {


NODE *new_node, *min_node, *extracted_min, *node_to_be_decrease, *find_use;
FIB_HEAP *heap, *h1, *h2;
int operation_no, new_key, dec_key, ele, i, no_of_nodes;
heap = (FIB_HEAP *)malloc(sizeof(FIB_HEAP));
heap = NULL;
while (1) {
printf(" \n Operations \n 1. Create Fibonacci heap \n 2. Insert nodes into fibonacci heap \n
3. Find min \n 4. Union \n 5. Extract min \n 6. Decrease key \n 7.Delete node \n 8. print
heap \n 9. exit \n enter operation_no = ");
scanf("%d", &operation_no);

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 ");
}
}
}

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy