Pairing Heap - GeeksforGeeks

01 Dec, 2021
Pairing Heap is like a simplified form Fibonacci Heap. It also maintains the property of min heap which is parent value is less than its child nodes value. It can be considered as a self-adjusting binomial heap.Each node has a pointer towards the left child and left child points towards the next sibling of the child. Example of Pairing Heap is given below:  
Join or Merge in Pairing Heap To join the two heap, first, we compare the root node of the heap if the root node of the first heap is smaller than the root node of the second heap then root node of the second heap becomes a left child of the root node of the first heap otherwise vice-versa. The time complexity of this process is O(1).Example of Merge is given Below:  
Insertion in Pairing Heap: To insert a new node in heap, create a new node and Merge it with existing heap as explained above. Therefore, the time complexity of this function is O(1). Example of Insertion is given below:  
Deletion in Pairing Heap: Deletion in Pairing Heap only happens at the root node. First delete links between root, left child and all the siblings of the left child. Then Merge tree subtrees that are obtained by detaching the left child and all siblings by the two pass method and delete the root node. Merge the detached subtrees from left to right in one pass and then merge the subtrees from right to left to form the new heap without violation of conditions of min-heap. This process takes O(log n) time where n is the number of nodes. Example of Deletion is given below:  
Below is the implementation of the above approach:  
CPP14
Python3
#include<bits/stdc++.h>using namespace std; // Heap structurestruct HeapNode {     int key;    HeapNode *leftChild;    HeapNode *nextSibling;     HeapNode():        leftChild(NULL), nextSibling(NULL) {}     // creates a new node    HeapNode(int key_, HeapNode *leftChild_, HeapNode *nextSibling_):        key(key_), leftChild(leftChild_), nextSibling(nextSibling_) {}                 // Adds a child and sibling to the node    void addChild(HeapNode *node) {        if(leftChild == NULL)            leftChild = node;        else {            node->nextSibling = leftChild;            leftChild = node;        }    }}; // Returns true if root of the tree// is null otherwise returns falsebool Empty(HeapNode *node) {    return (node == NULL);} // Function to merge two heapsHeapNode *Merge(HeapNode *A, HeapNode *B){    // If any of the two-nodes is null    // the return the not null node    if(A == NULL) return B;    if(B == NULL) return A;         // To maintain the min heap condition compare       // the nodes and node with minimum value become     // parent of the other node    if(A->key < B->key) {                         A->addChild(B);        return A;            }    else {        B->addChild(A);        return B;    }     return NULL; // Unreachable} // Returns the root value of the heapint Top(HeapNode *node) {    return node->key;} // Function to insert the new node in the heapHeapNode *Insert(HeapNode *node, int key) {    return Merge(node, new HeapNode(key, NULL, NULL));} // This method is used when we want to delete root nodeHeapNode *TwoPassMerge(HeapNode *node) {    if(node == NULL || node->nextSibling == NULL)        return node;    else {        HeapNode *A, *B, *newNode;        A = node;        B = node->nextSibling;        newNode = node->nextSibling->nextSibling;         A->nextSibling = NULL;        B->nextSibling = NULL;         return Merge(Merge(A, B), TwoPassMerge(newNode));    }     return NULL; // Unreachable} // Function to delete the root node in heapHeapNode *Delete(HeapNode *node) {    return TwoPassMerge(node->leftChild);} struct PairingHeap {    HeapNode *root;     PairingHeap():        root(NULL) {}     bool Empty(void) {        return ::Empty(root);    }     int Top(void) {        return ::Top(root);    }     void Insert(int key) {        root = ::Insert(root, key);    }     void Delete(void) {        root = ::Delete(root);    }     void Join(PairingHeap other) {        root = ::Merge(root, other.root);    }     }; // Driver Codeint main(void) {     PairingHeap heap1, heap2;    heap2.Insert(5);    heap2.Insert(2);     heap2.Insert(6);    heap1.Insert(1);    heap1.Insert(3);    heap1.Insert(4);         heap1.Join(heap2);         cout << heap1.Top() << endl;    heap1.Delete();     cout << heap1.Top() << endl;    cout<< (heap1.Empty()?"True":"False");         return 0;}
# Heap structureclass HeapNode:     # creates a new node    def __init__(self, key_=None, leftChild_=None, nextSibling_=None):        self.key = key_        self.leftChild = leftChild_        self.nextSibling = nextSibling_     # Adds a child and sibling to the node    def addChild(self, node):        if(self.leftChild == None):            self.leftChild = node        else:            node.nextSibling = self.leftChild            self.leftChild = node # Returns true if root of the tree# is None otherwise returns false  def Empty(node):    return (node == None) # Function to merge two heaps  def Merge(A, B):     # If any of the two-nodes is None    # the return the not None node    if(A == None):        return B    if(B == None):        return A     # To maintain the min heap condition compare    # the nodes and node with minimum value become    # parent of the other node    if(A.key < B.key):        A.addChild(B)        return A    B.addChild(A)    return B # Returns the root value of the heap  def Top(node):    return node.key  # Function to insert the new node in the heapdef Insert(node, key):    return Merge(node, HeapNode(key,))  # This method is used when we want to delete root nodedef TwoPassMerge(node):    if(node == None or node.nextSibling == None):        return node    A = node    B = node.nextSibling    newNode = node.nextSibling.nextSibling     A.nextSibling = None    B.nextSibling = None     return Merge(Merge(A, B), TwoPassMerge(newNode))  # Function to delete the root node in heapdef Delete(node):    return TwoPassMerge(node.leftChild)  class PairingHeap:    def __init__(self):        self.root = None     def Empty(self):        return Empty(self.root)     def Top(self):        return Top(self.root)     def Insert(self, key):        self.root = Insert(self.root, key)     def Delete(self):        self.root = Delete(self.root)     def Join(self, other):        self.root = Merge(self.root, other.root)  # Driver Codeif __name__ == '__main__':     heap1, heap2 = PairingHeap(), PairingHeap()    heap2.Insert(5)    heap2.Insert(2)     heap2.Insert(6)    heap1.Insert(1)    heap1.Insert(3)    heap1.Insert(4)     heap1.Join(heap2)     print(heap1.Top())    heap1.Delete()     print(heap1.Top())    print(heap1.Empty())# This code is contributed by Amartya Ghosh
1
2
False
 
Time Complexity: Insertion: O(1)Merge: O(1)Deletion: O(logN) Auxiliary Space: O(1).  
pankajsharmagfg
amartyaghoshgfg
Data Structures
Advanced Data Structure
Data Structures
Heap
Data Structures
Heap
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Ordered Set and GNU C++ PBDS
2-3 Trees | (Search, Insert and Deletion)
Extendible Hashing (Dynamic approach to DBMS)
Suffix Array | Set 1 (Introduction)
Interval Tree
SDE SHEET - A Complete Guide for SDE Preparation
Top 50 Array Coding Problems for Interviews
DSA Sheet by Love Babbar
Doubly Linked List | Set 1 (Introduction and Insertion)
Introduction to Algorithms