Open In App

Binomial Heap Using Python

Last Updated : 26 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Binomial Heap is an extension of Binary Heap that provides faster union or merge operations with other operations provided by Binary Heap. 

A Binomial Heap is a collection of Binomial Trees. The main application of Binary Heap is as implement a priority queue. To Know More about Binomial Heap Click here.

What is a Binomial Tree in Python? 

A Binomial Heap is a set of Binomial Trees where each Binomial Tree follows the operations Min Heap property. And there can be at most one Binomial Tree of any degree. It is explained in depth in the below illustration as follows:

Binomial Heap in Python

Example 1: A Binomial Heap with 12 nodes. It is a collection of 3—binomial Trees of orders 0, 2, and 3 from left to right.

firstdrawio

Example 1

Example 2: A Binomial Heap with 11 nodes. It is a collection of 2. Binomial Trees of orders 2 and 3 from left to right.  w

seconddrawio

Example 2

Operations of Binomial Heap Using Python

Below are some operations on binomial heaps which we will perform shortly using Python. Here, we talk about how to use Binomial Heap. We have these functions:

  • insert(H, k): Adds a key ‘k‘ to the Binomial Heap ‘H‘. First, it makes a new Binomial Heap with just ‘k‘, then combines it with H using the union function.
  • getMin(H): To find the smallest key in H, we can simply look through all the root nodes of the Binomial Trees and pick the smallest key. This way takes O(Logn) time. We can make it faster, O(1), by remembering where the smallest key is.
  • extractMin(H): This function also uses union(). First, it finds the smallest key Binomial Tree using getMin(). Then it removes that node and creates a new Binomial Heap by connecting all the sub-trees of the removed smallest node. Finally, it combines H with this new Binomial Heap using union(). This operation also takes O(Logn) time.

Implementation of Binomial Heap in Python

Python3
# A node representing a Binomial Tree.
class Node:
    def __init__(self, key):
        # Initialize node data,
        # degree, and pointers.
        self.data = key
        self.degree = 0
        self.child = None
        self.parent = None
        self.sibling = None

# Merges two Binomial Trees.

def mergeBinomialTrees(b1, b2):
    # Ensure b1 has smaller value.
    if b1.data > b2.data:
        b1, b2 = b2, b1

    # Make b2 a child of b1.
    b2.parent = b1
    b2.sibling = b1.child
    b1.child = b2
    b1.degree += 1

    return b1

# Performs union operation on two binomial heaps.

def unionBionomialHeap(l1, l2):
    _new = []
    it = ot = 0

    # Merge sorted lists based on degree.
    while it < len(l1) and ot < len(l2):
        if l1[it].degree <= l2[ot].degree:
            _new.append(l1[it])
            it += 1
        else:
            _new.append(l2[ot])
            ot += 1

    # Append remaining elements from lists.
    while it < len(l1):
        _new.append(l1[it])
        it += 1

    while ot < len(l2):
        _new.append(l2[ot])
        ot += 1

    return _new

# Rearranges the heap to ensure increasing order
# of degree and no two trees have the same degree.

def adjust(_heap):
    if len(_heap) <= 1:
        return _heap

    new_heap = []
    it1 = it2 = it3 = 0

    if len(_heap) == 2:
        it2 = 1
        it3 = len(_heap)
    else:
        it2 = 1
        it3 = 2

    while it1 < len(_heap):
        if it2 == len(_heap):
            it1 += 1

        elif _heap[it1].degree < _heap[it2].degree:
            it1 += 1
            it2 += 1
            if it3 < len(_heap):
                it3 += 1

        elif it3 < len(_heap) and _heap[it1].degree == _heap[it2].degree == _heap[it3].degree:
            it1 += 1
            it2 += 1
            it3 += 1

        elif _heap[it1].degree == _heap[it2].degree:
            # Merge trees with same degree.
            _heap[it1] = mergeBinomialTrees(_heap[it1], _heap[it2])
            del _heap[it2]
            if it3 < len(_heap):
                it3 += 1

    return _heap

# Inserts a Binomial Tree into a binomial heap.


def insertATreeInHeap(_heap, tree):
    temp = [tree]
    temp = unionBionomialHeap(_heap, temp)
    return adjust(temp)

# Removes the minimum key element from the binomial heap
# and returns the binomial heap.

def removeMinFromTreeReturnBHeap(tree):
    heap = []
    temp = tree.child

    # Create a heap from the children of the minimum element.
    while temp:
        lo = temp
        temp = temp.sibling
        lo.sibling = None
        heap.insert(0, lo)

    return heap

# Inserts a key into the binomial heap.

def insert(_head, key):
    temp = Node(key)
    return insertATreeInHeap(_head, temp)

# Returns the pointer of the minimum value Node present
# in the binomial heap.

def getMin(_heap):
    temp = _heap[0]

    # Find the minimum element in the heap.
    for node in _heap:
        if node.data < temp.data:
            temp = node

    return temp

# Extracts the minimum element from the binomial heap.

def extractMin(_heap):
    new_heap = []
    lo = []

    # Get the minimum element.
    temp = getMin(_heap)

    # Remove the minimum element from the heap.
    for node in _heap:
        if node != temp:
            new_heap.append(node)

    # Merge heap with children of the minimum element.
    lo = removeMinFromTreeReturnBHeap(temp)
    new_heap = unionBionomialHeap(new_heap, lo)
    new_heap = adjust(new_heap)

    return new_heap

# Prints a Binomial Tree.

def printTree(h):
    while h:
        # Print current node's data.
        print(h.data, end=" ")
        # Recursively print child nodes.
        printTree(h.child)
        h = h.sibling

# Prints a binomial heap.

def printHeap(_heap):
    for node in _heap:
        # Print each Binomial Tree in the heap.
        printTree(node)

# Driver program to test the functions.
if __name__ == "__main__":
    _heap = []

    # Insert data into the heap.
    _heap = insert(_heap, 10)
    _heap = insert(_heap, 20)
    _heap = insert(_heap, 30)

    print("Heap elements after insertion:")
    # Print the heap after insertion.
    printHeap(_heap)

    # Find and print the minimum element.
    temp = getMin(_heap)
    print("\nMinimum element of heap:", temp.data)

    # Delete the minimum element from the heap.
    _heap = extractMin(_heap)
    print("Heap after deletion of minimum element:")
    # Print the heap after deletion.
    printHeap(_heap)

Output
Heap elements after insertion:
30 10 20 
Minimum element of heap: 10
Heap after deletion of minimum element:
20 30 

Time Complexity:

  • Insertion and removal of minimum element: O(log n)
  • Finding the minimum element: O(n)

Space Complexity: O(n)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads