Implementation of Binomial Heap | Set – 2 (delete() and decreseKey())

In previous post i.e. Set 1 we have discussed that implements these below functions:

  1. insert(H, k): Inserts a key ‘k’ to Binomial Heap ‘H’. This operation first creates a Binomial Heap with single key ‘k’, then calls union on H and the new Binomial heap.
  2. getMin(H): A simple way to getMin() is to traverse the list of root of Binomial Trees and return the minimum key. This implementation requires O(Logn) time. It can be optimized to O(1) by maintaining a pointer to minimum key root.
  3. extractMin(H): This operation also uses union(). We first call getMin() to find the minimum key Binomial Tree, then we remove the node and create a new Binomial Heap by connecting all subtrees of the removed minimum node. Finally we call union() on H and the newly created Binomial Heap. This operation requires O(Logn) time.

Examples:

12------------10--------------------20
             /  \                 /  | \
           15    50             70  50  40
           |                  / |    |     
           30               80  85  65 
                            |
                           100
A Binomial Heap with 13 nodes. It is a collection of 3 
Binomial Trees of orders 0, 2 and 3 from left to right. 

    10--------------------20
   /  \                 /  | \
 15    50             70  50  40
 |                  / |    |     
 30               80  85  65 
                  |
                 100

In this post, below functions are implemented.



  1. delete(H): Like Binary Heap, delete operation first reduces the key to minus infinite, then calls extractMin().
  2. decreaseKey(H): decreaseKey() is also similar to Binary Heap. We compare the decreases key with it parent and if parent’s key is more, we swap keys and recur for parent. We stop when we either reach a node whose parent has smaller key or we hit the root node. Time complexity of decreaseKey() is O(Logn)
filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for implementation of
// Binomial Heap and Operations on it
#include <bits/stdc++.h>
using namespace std;
  
// Structure of Node
struct Node
{
    int val, degree;
    Node *parent, *child, *sibling;
};
  
// Making root global to avoid one extra
// parameter in all functions.
Node *root = NULL;
  
// link two heaps by making h1 a child
// of h2.
int binomialLink(Node *h1, Node *h2)
{
    h1->parent = h2;
    h1->sibling = h2->child;
    h2->child = h1;
    h2->degree = h2->degree + 1;
}
  
// create a Node
Node *createNode(int n)
{
    Node *new_node = new Node;
    new_node->val = n;
    new_node->parent = NULL;
    new_node->sibling = NULL;
    new_node->child = NULL;
    new_node->degree = 0;
    return new_node;
}
  
// This function merge two Binomial Trees
Node *mergeBHeaps(Node *h1, Node *h2)
{
    if (h1 == NULL)
        return h2;
    if (h2 == NULL)
        return h1;
  
    // define a Node
    Node *res = NULL;
  
    // check degree of both Node i.e.
    // which is greater or smaller
    if (h1->degree <= h2->degree)
        res = h1;
  
    else if (h1->degree > h2->degree)
        res = h2;
  
    // traverse till if any of heap gets empty
    while (h1 != NULL && h2 != NULL)
    {
        // if degree of h1 is smaller, increment h1
        if (h1->degree < h2->degree)
            h1 = h1->sibling;
  
        // Link h1 with h2 in case of equal degree
        else if (h1->degree == h2->degree)
        {
            Node *sib = h1->sibling;
            h1->sibling = h2;
            h1 = sib;
        }
  
        // if h2 is greater
        else
        {
            Node *sib = h2->sibling;
            h2->sibling = h1;
            h2 = sib;
        }
    }
    return res;
}
  
// This function perform union operation on two
// binomial heap i.e. h1 & h2
Node *unionBHeaps(Node *h1, Node *h2)
{
    if (h1 == NULL && h2 == NULL)
       return NULL;
  
    Node *res = mergeBHeaps(h1, h2);
  
    // Traverse the merged list and set
    // values according to the degree of
    // Nodes
    Node *prev = NULL, *curr = res,
         *next = curr->sibling;
    while (next != NULL)
    {
        if ((curr->degree != next->degree) ||
                ((next->sibling != NULL) &&
                 (next->sibling)->degree ==
                 curr->degree))
        {
            prev = curr;
            curr = next;
        }
  
        else
        {
            if (curr->val <= next->val)
            {
                curr->sibling = next->sibling;
                binomialLink(next, curr);
            }
            else
            {
                if (prev == NULL)
                    res = next;
                else
                    prev->sibling = next;
                binomialLink(curr, next);
                curr = next;
            }
        }
        next = curr->sibling;
    }
    return res;
}
  
// Function to insert a Node
void binomialHeapInsert(int x)
{
    // Create a new node and do union of
    // this node with root
    root = unionBHeaps(root, createNode(x));
}
  
// Function to display the Nodes
void display(Node *h)
{
    while (h)
    {
        cout << h->val << " ";
        display(h->child);
        h = h->sibling;
    }
}
  
// Function to reverse a list
// using recursion.
int revertList(Node *h)
{
    if (h->sibling != NULL)
    {
        revertList(h->sibling);
        (h->sibling)->sibling = h;
    }
    else
        root = h;
}
  
// Function to extract minimum value
Node *extractMinBHeap(Node *h)
{
    if (h == NULL)
       return NULL;
  
    Node *min_node_prev = NULL;
    Node *min_node = h;
  
    // Find minimum value
    int min = h->val;
    Node *curr = h;
    while (curr->sibling != NULL)
    {
        if ((curr->sibling)->val < min)
        {
            min = (curr->sibling)->val;
            min_node_prev = curr;
            min_node = curr->sibling;
        }
        curr = curr->sibling;
    }
  
    // If there is a single Node
    if (min_node_prev == NULL &&
        min_node->sibling == NULL)
        h = NULL;
  
    else if (min_node_prev == NULL)
        h = min_node->sibling;
  
    // Remove min node from list
    else
        min_node_prev->sibling = min_node->sibling;
  
    // Set root (which is global) as children
    // list of min node
    if (min_node->child != NULL)
    {
        revertList(min_node->child);
        (min_node->child)->sibling = NULL;
    }
  
    // Do union of root h and children
    return unionBHeaps(h, root);
}
  
// Function to search for an element
Node *findNode(Node *h, int val)
{
    if (h == NULL)
      return NULL;
  
     // check if key is equal to the root's data
    if (h->val == val)
        return h;
  
    // Recur for child
    Node *res = findNode(h->child, val);
    if (res != NULL)
       return res;
  
    return findNode(h->sibling, val);
}
  
// Function to decrease the value of old_val
// to new_val
void decreaseKeyBHeap(Node *H, int old_val,
                               int new_val)
{
    // First check element present or not
    Node *node = findNode(H, old_val);
  
    // return if Node is not present
    if (node == NULL)
        return;
  
    // Reduce the value to the minimum
    node->val = new_val;
    Node *parent = node->parent;
  
    // Update the heap according to reduced value
    while (parent != NULL && node->val < parent->val)
    {
        swap(node->val, parent->val);
        node = parent;
        parent = parent->parent;
    }
}
  
// Function to delete an element
Node *binomialHeapDelete(Node *h, int val)
{
    // Check if heap is empty or not
    if (h == NULL)
        return NULL;
  
    // Reduce the value of element to minimum
    decreaseKeyBHeap(h, val, INT_MIN);
  
    // Delete the minimum element from heap
    return extractMinBHeap(h);
}
  
// Driver code
int main()
{
    // Note that root is global
    binomialHeapInsert(10);
    binomialHeapInsert(20);
    binomialHeapInsert(30);
    binomialHeapInsert(40);
    binomialHeapInsert(50);
  
    cout << "The heap is:\n";
    display(root);
  
    // Delete a particular element from heap
    root = binomialHeapDelete(root, 10);
  
    cout << "\nAfter deleing 10, the heap is:\n";
  
    display(root);
  
    return 0;
}

chevron_right


Output:

The heap is:
50 10 30 40 20 
After deleing 10, the heap is:
20 30 40 50 


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.