Fibonacci Heap – Deletion, Extract min and Decrease key
In the last post, we discussed the Insertion and Union of Fibonacci Heaps. In this post, we will discuss Extract_min(), Decrease_key() and Deletion() operations on Fibonacci heap.
Prerequisites:
Fibonacci Heap (Introduction)
Fibonacci Heap – Insertion and Union
Extract_min():
We create a function for deleting the minimum node and setting the min pointer to the minimum value in the remaining heap. The following algorithm is followed:
- Delete the min node.
- Set head to the next min node and add all the trees of the deleted node in the root list.
- Create an array of degree pointers of the size of the deleted node.
- Set degree pointer to the current node.
- Move to the next node.
- If degrees are different then set degree pointer to next node.
- If degrees are the same then join the Fibonacci trees by union operation.
- Repeat steps 4 and 5 until the heap is completed.
Example:
Decrease_key():
To decrease the value of any element in the heap, we follow the following algorithm:
- Decrease the value of the node ‘x’ to the new chosen value.
- CASE 1) If min-heap property is not violated,
- Update min pointer if necessary.
- CASE 2) If min-heap property is violated and parent of ‘x’ is unmarked,
- Cut off the link between ‘x’ and its parent.
- Mark the parent of ‘x’.
- Add tree rooted at ‘x’ to the root list and update min pointer if necessary.
- CASE 3)If min-heap property is violated and parent of ‘x’ is marked,
- Cut off the link between ‘x’ and its parent p[x].
- Add ‘x’ to the root list, updating min pointer if necessary.
- Cut off link between p[x] and p[p[x]].
- Add p[x] to the root list, updating min pointer if necessary.
- If p[p[x]] is unmarked, mark it.
- Else, cut off p[p[x]] and repeat steps 4.2 to 4.5, taking p[p[x]] as ‘x’.
Example:
Deletion():
To delete any element in a Fibonacci heap, the following algorithm is followed:
- Decrease the value of the node to be deleted ‘x’ to a minimum by Decrease_key() function.
- By using min-heap property, heapify the heap containing ‘x’, bringing ‘x’ to the root list.
- Apply Extract_min() algorithm to the Fibonacci heap.
Example:
Following is a program to demonstrate Extract min(), Deletion() and Decrease key() operations on a Fibonacci Heap:
C++
// C++ program to demonstrate Extract min, Deletion() // and Decrease key() operations in a fibonacci heap #include <cmath> #include <cstdlib> #include <iostream> #include <malloc.h> using namespace std; // Creating a structure to represent a node in the heap struct node { node* parent; // Parent pointer node* child; // Child pointer node* left; // Pointer to the node on the left node* right; // Pointer to the node on the right int key; // Value of the node int degree; // Degree of the node char mark; // Black or white mark of the node char c; // Flag for assisting in the Find node function }; // Creating min pointer as "mini" struct node* mini = NULL; // Declare an integer for number of nodes in the heap int no_of_nodes = 0; // Function to insert a node in heap void insertion( int val) { struct node* new_node = new node(); new_node->key = val; new_node->degree = 0; new_node->mark = 'W' ; new_node->c = 'N' ; new_node->parent = NULL; new_node->child = NULL; new_node->left = new_node; new_node->right = new_node; if (mini != NULL) { (mini->left)->right = new_node; new_node->right = mini; new_node->left = mini->left; mini->left = new_node; if (new_node->key < mini->key) mini = new_node; } else { mini = new_node; } no_of_nodes++; } // Linking the heap nodes in parent child relationship void Fibonnaci_link( struct node* ptr2, struct node* ptr1) { (ptr2->left)->right = ptr2->right; (ptr2->right)->left = ptr2->left; if (ptr1->right == ptr1) mini = ptr1; ptr2->left = ptr2; ptr2->right = ptr2; ptr2->parent = ptr1; if (ptr1->child == NULL) ptr1->child = ptr2; ptr2->right = ptr1->child; ptr2->left = (ptr1->child)->left; ((ptr1->child)->left)->right = ptr2; (ptr1->child)->left = ptr2; if (ptr2->key < (ptr1->child)->key) ptr1->child = ptr2; ptr1->degree++; } // Consolidating the heap void Consolidate() { int temp1; float temp2 = ( log (no_of_nodes)) / ( log (2)); int temp3 = temp2; struct node* arr[temp3+1]; for ( int i = 0; i <= temp3; i++) arr[i] = NULL; node* ptr1 = mini; node* ptr2; node* ptr3; node* ptr4 = ptr1; do { ptr4 = ptr4->right; temp1 = ptr1->degree; while (arr[temp1] != NULL) { ptr2 = arr[temp1]; if (ptr1->key > ptr2->key) { ptr3 = ptr1; ptr1 = ptr2; ptr2 = ptr3; } if (ptr2 == mini) mini = ptr1; Fibonnaci_link(ptr2, ptr1); if (ptr1->right == ptr1) mini = ptr1; arr[temp1] = NULL; temp1++; } arr[temp1] = ptr1; ptr1 = ptr1->right; } while (ptr1 != mini); mini = NULL; for ( int j = 0; j <= temp3; j++) { if (arr[j] != NULL) { arr[j]->left = arr[j]; arr[j]->right = arr[j]; if (mini != NULL) { (mini->left)->right = arr[j]; arr[j]->right = mini; arr[j]->left = mini->left; mini->left = arr[j]; if (arr[j]->key < mini->key) mini = arr[j]; } else { mini = arr[j]; } if (mini == NULL) mini = arr[j]; else if (arr[j]->key < mini->key) mini = arr[j]; } } } // Function to extract minimum node in the heap void Extract_min() { if (mini == NULL) cout << "The heap is empty" << endl; else { node* temp = mini; node* pntr; pntr = temp; node* x = NULL; if (temp->child != NULL) { x = temp->child; do { pntr = x->right; (mini->left)->right = x; x->right = mini; x->left = mini->left; mini->left = x; if (x->key < mini->key) mini = x; x->parent = NULL; x = pntr; } while (pntr != temp->child); } (temp->left)->right = temp->right; (temp->right)->left = temp->left; mini = temp->right; if (temp == temp->right && temp->child == NULL) mini = NULL; else { mini = temp->right; Consolidate(); } no_of_nodes--; } } // Cutting a node in the heap to be placed in the root list void Cut( struct node* found, struct node* temp) { if (found == found->right) temp->child = NULL; (found->left)->right = found->right; (found->right)->left = found->left; if (found == temp->child) temp->child = found->right; temp->degree = temp->degree - 1; found->right = found; found->left = found; (mini->left)->right = found; found->right = mini; found->left = mini->left; mini->left = found; found->parent = NULL; found->mark = 'B' ; } // Recursive cascade cutting function void Cascase_cut( struct node* temp) { node* ptr5 = temp->parent; if (ptr5 != NULL) { if (temp->mark == 'W' ) { temp->mark = 'B' ; } else { Cut(temp, ptr5); Cascase_cut(ptr5); } } } // Function to decrease the value of a node in the heap void Decrease_key( struct node* found, int val) { if (mini == NULL) cout << "The Heap is Empty" << endl; if (found == NULL) cout << "Node not found in the Heap" << endl; found->key = val; struct node* temp = found->parent; if (temp != NULL && found->key < temp->key) { Cut(found, temp); Cascase_cut(temp); } if (found->key < mini->key) mini = found; } // Function to find the given node void Find( struct node* mini, int old_val, int val) { struct node* found = NULL; node* temp5 = mini; temp5->c = 'Y' ; node* found_ptr = NULL; if (temp5->key == old_val) { found_ptr = temp5; temp5->c = 'N' ; found = found_ptr; Decrease_key(found, val); } if (found_ptr == NULL) { if (temp5->child != NULL) Find(temp5->child, old_val, val); if ((temp5->right)->c != 'Y' ) Find(temp5->right, old_val, val); } temp5->c = 'N' ; found = found_ptr; } // Deleting a node from the heap void Deletion( int val) { if (mini == NULL) cout << "The heap is empty" << endl; else { // Decreasing the value of the node to 0 Find(mini, val, 0); // Calling Extract_min function to // delete minimum value node, which is 0 Extract_min(); cout << "Key Deleted" << endl; } } // Function to display the heap void display() { node* ptr = mini; if (ptr == NULL) cout << "The Heap is Empty" << endl; else { cout << "The root nodes of Heap are: " << endl; do { cout << ptr->key; ptr = ptr->right; if (ptr != mini) { cout << "-->" ; } } while (ptr != mini && ptr->right != NULL); cout << endl << "The heap has " << no_of_nodes << " nodes" << endl << endl; } } // Driver code int main() { // We will create a heap and insert 3 nodes into it cout << "Creating an initial heap" << endl; insertion(5); insertion(2); insertion(8); // Now we will display the root list of the heap display(); // Now we will extract the minimum value node from the heap cout << "Extracting min" << endl; Extract_min(); display(); // Now we will decrease the value of node '8' to '7' cout << "Decrease value of 8 to 7" << endl; Find(mini, 8, 7); display(); // Now we will delete the node '7' cout << "Delete the node 7" << endl; Deletion(7); display(); return 0; } |
Python3
# Python3 program to demonstrate Extract min, Deletion() # and Decrease key() operations in a fibonacci heap import math # Creating a class to represent a node in the heap class node: def __init__( self ): parent = None # Parent pointer child = None # Child pointer left = None # Pointer to the node on the left right = None # Pointer to the node on the right key = - 1 # Value of the node degree = - 1 # Degree of the node mark = '' # Black or white mark of the node c = '' # Flag for assisting in the Find node function # Creating min pointer as "mini" mini = None # Declare an integer for number of nodes in the heap no_of_nodes = 0 # Function to insert a node in heap def insertion(val): global mini,no_of_nodes new_node = node() new_node.key = val new_node.degree = 0 new_node.mark = 'W' new_node.c = 'N' new_node.parent = None new_node.child = None new_node.left = new_node new_node.right = new_node if (mini ! = None ): mini.left.right = new_node new_node.right = mini new_node.left = mini.left mini.left = new_node if (new_node.key < mini.key): mini = new_node else : mini = new_node no_of_nodes + = 1 # Linking the heap nodes in parent child relationship def Fibonnaci_link(ptr2, ptr1): ptr2.left.right = ptr2.right ptr2.right.left = ptr2.left if (ptr1.right = = ptr1): mini = ptr1 ptr2.left = ptr2 ptr2.right = ptr2 ptr2.parent = ptr1 if (ptr1.child = = None ): ptr1.child = ptr2 ptr2.right = ptr1.child ptr2.left = ptr1.child.left ptr1.child.left.right = ptr2 ptr1.child.left = ptr2 if ptr2.key < ptr1.child.key: ptr1.child = ptr2 ptr1.degree + = 1 # Consolidating the heap def Consolidate(): global mini temp2 = math.log2(no_of_nodes) temp3 = int (temp2) arr = [ None ] * (temp3 + 1 ) for i in range (temp3 + 1 ): arr[i] = None ptr1 = mini ptr4 = ptr1 while True : ptr4 = ptr4.right temp1 = ptr1.degree while (arr[temp1] ! = None ): ptr2 = arr[temp1] if (ptr1.key > ptr2.key): ptr3 = ptr1 ptr1 = ptr2 ptr2 = ptr3 if (ptr2 = = mini): mini = ptr1 Fibonnaci_link(ptr2, ptr1) if (ptr1.right = = ptr1): mini = ptr1 arr[temp1] = None temp1 + = 1 arr[temp1] = ptr1 ptr1 = ptr1.right if (ptr1 = = mini): break mini = None for j in range (temp3 + 1 ): if (arr[j] ! = None ): arr[j].left = arr[j] arr[j].right = arr[j] if (mini ! = None ) : mini.left.right = arr[j] arr[j].right = mini arr[j].left = mini.left mini.left = arr[j] if (arr[j].key < mini.key): mini = arr[j] else : mini = arr[j] if mini = = None : mini = arr[j] elif arr[j].key < mini.key: mini = arr[j] # Function to extract minimum node in the heap def Extract_min(): global mini,no_of_nodes if mini = = None : print ( "The heap is empty" ) else : temp = mini pntr = temp x = None if (temp.child ! = None ): x = temp.child while ( True ): pntr = x.right mini.left.right = x x.right = mini x.left = mini.left mini.left = x if x.key < mini.key: mini = x x.parent = None x = pntr if (pntr = = temp.child): break temp.left.right = temp.right temp.right.left = temp.left mini = temp.right if temp = = temp.right and temp.child = = None : mini = None else : mini = temp.right Consolidate() no_of_nodes - = 1 # Cutting a node in the heap to be placed in the root list def Cut(found, temp): if (found = = found.right): temp.child = None found.left.right = found.right found.right.left = found.left if (found = = temp.child): temp.child = found.right temp.degree = temp.degree - 1 found.right = found found.left = found mini.left.right = found found.right = mini found.left = mini.left mini.left = found found.parent = None found.mark = 'B' # Recursive cascade cutting function def Cascase_cut(temp): ptr5 = temp.parent if (ptr5 ! = None ): if (temp.mark = = 'W' ): temp.mark = 'B' else : Cut(temp, ptr5) Cascase_cut(ptr5) # Function to decrease the value of a node in the heap def Decrease_key(found, val): global mini if (mini = = None ): print ( "The Heap is Empty" ) if found = = None : print ( "Node not found in the Heap" ) found.key = val temp = found.parent if (temp ! = None and found.key < temp.key): Cut(found, temp) Cascase_cut(temp) if (found.key < mini.key): mini = found # Function to find the given node def Find(mini, old_val, val): found = None temp5 = mini temp5.c = 'Y' found_ptr = None if (temp5.key = = old_val): found_ptr = temp5 temp5.c = 'N' found = found_ptr Decrease_key(found, val) if (found_ptr = = None ): if (temp5.child ! = None ): Find(temp5.child, old_val, val) if temp5.right.c ! = 'Y' : Find(temp5.right, old_val, val) temp5.c = 'N' found = found_ptr # Deleting a node from the heap def Deletion(val): if (mini = = None ): print ( "The heap is empty" ) else : # Decreasing the value of the node to 0 Find(mini, val, 0 ) # Calling Extract_min function to # delete minimum value node, which is 0 Extract_min() print ( "Key Deleted" ) # Function to display the heap def display(): ptr = mini if (ptr = = None ): print ( "The Heap is Empty" ) else : print ( "The root nodes of Heap are: " ) while ( True ): print (ptr.key,end = '') ptr = ptr.right if (ptr ! = mini): print ( "-->" ,end = '') if not (ptr ! = mini and ptr.right ! = None ): break print () print ( "The heap has {} nodes" . format (no_of_nodes)) # Driver code if __name__ = = '__main__' : # We will create a heap and insert 3 nodes into it print ( "Creating an initial heap" ) insertion( 5 ) insertion( 2 ) insertion( 8 ) # Now we will display the root list of the heap display() # Now we will extract the minimum value node from the heap print ( "Extracting min" ) Extract_min() display() # Now we will decrease the value of node '8' to '7' print ( "Decrease value of 8 to 7" ) Find(mini, 8 , 7 ) display() print ( "Now we will delete the node '7'" ) print ( "Delete the node 7" ) Deletion( 7 ) display() # This code is contributed by Amartya Ghosh |
Creating an initial heap The root nodes of Heap are: 2-->5-->8 The heap has 3 nodes Extracting min The root nodes of Heap are: 5 The heap has 2 nodes Decrease value of 8 to 7 The root nodes of Heap are: 5 The heap has 2 nodes Delete the node 7 Key Deleted The root nodes of Heap are: 5 The heap has 1 nodes
Please Login to comment...