Fibonacci Heap data structure
Fibonacci Heap data structure
Fibonacci heap data structure used to Fibonacci numbers and to implement the priority queue element in Dijkstra’s shortest path algorithm which decrease the time complexity from O(m log n) to O(m + n log n).
This heap is called a fibonacci heap because the trees are arrranged in such a way that tree of order n
has at least F
n+2 nodes in it, where F
n+2 is the (n + 2)
th Fibonacci number.
Properties of a Fibonacci Heap
- Fibonacci Heap a set of min heap-ordered trees. (i.e. The parent is always smaller than the children.)
- A pointer is maintained at the smallest element node.
- The trees within a Fibonacci heap are unordered but it is rooted.
Operations on a Fibonacci Heap
1. Insertion
Algorithm of Insertion in Fibonacci heap
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
2. Find Min
The minimum element is always given by the min pointer.
3. Union
Union is a concatenates the root lists of two Fibonacci heaps and sets the minimum node to which tree’s minimum node is smaller
Algorithm of union
Join root lists of Fibonacci heaps H1 and H2 and make a single Fibonacci heap H. If H1(min) < H2(min) then: H(min) = H1(min). Else: H(min) = H2(min).
Program for Operation of Fibonacci Heap in C++
#include <cmath> #include <cstdlib> #include <iostream> using namespace std; // Node creation struct node { int n; int degree; node *parent; node *child; node *left; node *right; char mark; char C; }; // Implementation of Fibonacci heap class FibonacciHeap { private: int nH; node *H; public: node *InitializeHeap(); int Fibonnaci_link(node *, node *, node *); node *Create_node(int); node *Insert(node *, node *); node *Union(node *, node *); node *Extract_Min(node *); int Consolidate(node *); int Display(node *); node *Find(node *, int); int Decrease_key(node *, int, int); int Delete_key(node *, int); int Cut(node *, node *, node *); int Cascase_cut(node *, node *); FibonacciHeap() { H = InitializeHeap(); } }; // Initialize heap node *FibonacciHeap::InitializeHeap() { node *np; np = NULL; return np; } // Create node node *FibonacciHeap::Create_node(int value) { node *x = new node; x->n = value; return x; } // Insert node node *FibonacciHeap::Insert(node *H, node *x) { x->degree = 0; x->parent = NULL; x->child = NULL; x->left = x; x->right = x; x->mark = 'F'; x->C = 'N'; if (H != NULL) { (H->left)->right = x; x->right = H; x->left = H->left; H->left = x; if (x->n < H->n) H = x; } else { H = x; } nH = nH + 1; return H; } // Create linking int FibonacciHeap::Fibonnaci_link(node *H1, node *y, node *z) { (y->left)->right = y->right; (y->right)->left = y->left; if (z->right == z) H1 = z; y->left = y; y->right = y; y->parent = z; if (z->child == NULL) z->child = y; y->right = z->child; y->left = (z->child)->left; ((z->child)->left)->right = y; (z->child)->left = y; if (y->n < (z->child)->n) z->child = y; z->degree++; } // Union Operation node *FibonacciHeap::Union(node *H1, node *H2) { node *np; node *H = InitializeHeap(); H = H1; (H->left)->right = H2; (H2->left)->right = H; np = H->left; H->left = H2->left; H2->left = np; return H; } // Display the heap int FibonacciHeap::Display(node *H) { node *p = H; if (p == NULL) { cout << "Empty Heap" << endl; return 0; } cout << "Root Nodes: " << endl; do { cout << p->n; p = p->right; if (p != H) { cout << "-->"; } } while (p != H && p->right != NULL); cout << endl; } // Extract min node *FibonacciHeap::Extract_Min(node *H1) { node *p; node *ptr; node *z = H1; p = z; ptr = z; if (z == NULL) return z; node *x; node *np; x = NULL; if (z->child != NULL) x = z->child; if (x != NULL) { ptr = x; do { np = x->right; (H1->left)->right = x; x->right = H1; x->left = H1->left; H1->left = x; if (x->n < H1->n) H1 = x; x->parent = NULL; x = np; } while (np != ptr); } (z->left)->right = z->right; (z->right)->left = z->left; H1 = z->right; if (z == z->right && z->child == NULL) H = NULL; else { H1 = z->right; Consolidate(H1); } nH = nH - 1; return p; } // Consolidation Function int FibonacciHeap::Consolidate(node *H1) { int d, i; float f = (log(nH)) / (log(2)); int D = f; node *A[D]; for (i = 0; i <= D; i++) A[i] = NULL; node *x = H1; node *y; node *np; node *pt = x; do { pt = pt->right; d = x->degree; while (A[d] != NULL) { y = A[d]; if (x->n > y->n) { np = x; x = y; y = np; } if (y == H1) H1 = x; Fibonnaci_link(H1, y, x); if (x->right == x) H1 = x; A[d] = NULL; d = d + 1; } A[d] = x; x = x->right; } while (x != H1); H = NULL; for (int j = 0; j <= D; j++) { if (A[j] != NULL) { A[j]->left = A[j]; A[j]->right = A[j]; if (H != NULL) { (H->left)->right = A[j]; A[j]->right = H; A[j]->left = H->left; H->left = A[j]; if (A[j]->n < H->n) H = A[j]; } else { H = A[j]; } if (H == NULL) H = A[j]; else if (A[j]->n < H->n) H = A[j]; } } } // Decrease Key Operation int FibonacciHeap::Decrease_key(node *H1, int x, int k) { node *y; if (H1 == NULL) { cout << "The Heap is Empty" << endl; return 0; } node *ptr = Find(H1, x); if (ptr == NULL) { cout << "Node not found in the Heap" << endl; return 1; } if (ptr->n < k) { cout << "Entered key greater than current key" << endl; return 0; } ptr->n = k; y = ptr->parent; if (y != NULL && ptr->n < y->n) { Cut(H1, ptr, y); Cascase_cut(H1, y); } if (ptr->n < H->n) H = ptr; return 0; } // Cutting Function int FibonacciHeap::Cut(node *H1, node *x, node *y) { if (x == x->right) y->child = NULL; (x->left)->right = x->right; (x->right)->left = x->left; if (x == y->child) y->child = x->right; y->degree = y->degree - 1; x->right = x; x->left = x; (H1->left)->right = x; x->right = H1; x->left = H1->left; H1->left = x; x->parent = NULL; x->mark = 'F'; } // Cascade cut int FibonacciHeap::Cascase_cut(node *H1, node *y) { node *z = y->parent; if (z != NULL) { if (y->mark == 'F') { y->mark = 'T'; } else { Cut(H1, y, z); Cascase_cut(H1, z); } } } // Search function node *FibonacciHeap::Find(node *H, int k) { node *x = H; x->C = 'Y'; node *p = NULL; if (x->n == k) { p = x; x->C = 'N'; return p; } if (p == NULL) { if (x->child != NULL) p = Find(x->child, k); if ((x->right)->C != 'Y') p = Find(x->right, k); } x->C = 'N'; return p; } // Deleting key int FibonacciHeap::Delete_key(node *H1, int k) { node *np = NULL; int t; t = Decrease_key(H1, k, -5000); if (!t) np = Extract_Min(H); if (np != NULL) cout << "Key Deleted" << endl; else cout << "Key not Deleted" << endl; return 0; } int main() { int n, m, l; FibonacciHeap fh; node *p; node *H; H = fh.InitializeHeap(); p = fh.Create_node(7); H = fh.Insert(H, p); p = fh.Create_node(3); H = fh.Insert(H, p); p = fh.Create_node(17); H = fh.Insert(H, p); p = fh.Create_node(24); H = fh.Insert(H, p); fh.Display(H); p = fh.Extract_Min(H); if (p != NULL) cout << "The node with minimum key: " << p->n << endl; else cout << "Heap is empty" << endl; m = 26; l = 16; fh.Decrease_key(H, m, l); m = 16; fh.Delete_key(H, m); }
Output
Root Nodes: 3-->7-->17-->24 The node with minimum key: 3 Node not found in the Heap Node not found in the Heap Key not Deleted
Program for Operation of Fibonacci Heap in Python
import math # Creating fibonacci tree class FibonacciTree: def __init__(self, value): self.value = value self.child = [] self.order = 0 # Adding tree at the end of the tree def add_at_end(self, t): self.child.append(t) self.order = self.order + 1 # Creating Fibonacci heap class FibonacciHeap: def __init__(self): self.trees = [] self.least = None self.count = 0 # Insert a node def insert_node(self, value): new_tree = FibonacciTree(value) self.trees.append(new_tree) if (self.least is None or value < self.least.value): self.least = new_tree self.count = self.count + 1 # Get minimum value def get_min(self): if self.least is None: return None return self.least.value # Extract the minimum value def extract_min(self): smallest = self.least if smallest is not None: for child in smallest.child: self.trees.append(child) self.trees.remove(smallest) if self.trees == []: self.least = None else: self.least = self.trees[0] self.consolidate() self.count = self.count - 1 return smallest.value # Consolidate the tree def consolidate(self): aux = (floor_log(self.count) + 1) * [None] while self.trees != []: x = self.trees[0] order = x.order self.trees.remove(x) while aux[order] is not None: y = aux[order] if x.value > y.value: x, y = y, x x.add_at_end(y) aux[order] = None order = order + 1 aux[order] = x self.least = None for k in aux: if k is not None: self.trees.append(k) if (self.least is None or k.value < self.least.value): self.least = k def floor_log(x): return math.frexp(x)[1] - 1 fibonacci_heap = FibonacciHeap() fibonacci_heap.insert_node(7) fibonacci_heap.insert_node(3) fibonacci_heap.insert_node(17) fibonacci_heap.insert_node(24) print('the minimum value of the fibonacci heap: {}'.format(fibonacci_heap.get_min())) print('the minimum value removed: {}'.format(fibonacci_heap.extract_min()))
Output
the minimun value of the fibonacci heap: 3 the minimum value removed: 3
Read more, Heap Data Structure