GFG App
Open App
Browser
Continue

# Pairing Heap

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

 `#include` `using` `namespace` `std;`   `// Heap structure` `struct` `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 false` `bool` `Empty(HeapNode *node) { ` `    ``return` `(node == NULL);` `}`   `// Function to merge two heaps` `HeapNode *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 heap` `int` `Top(HeapNode *node) {` `    ``return` `node->key; ` `}`   `// Function to insert the new node in the heap` `HeapNode *Insert(HeapNode *node, ``int` `key) {` `    ``return` `Merge(node, ``new` `HeapNode(key, NULL, NULL));` `}`   `// This method is used when we want to delete root node` `HeapNode *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 heap` `HeapNode *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 Code` `int` `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;` `}`

## Java

 `import` `java.util.*;`   `// Heap structure` `class` `HeapNode {`   `    ``int` `key;` `    ``HeapNode leftChild;` `    ``HeapNode nextSibling;`   `    ``public` `HeapNode() {` `        ``leftChild = ``null``;` `        ``nextSibling = ``null``;` `    ``}`   `    ``// creates a new node` `    ``public` `HeapNode(``int` `key_, HeapNode leftChild_, HeapNode nextSibling_) {` `        ``key = key_;` `        ``leftChild = leftChild_;` `        ``nextSibling = nextSibling_;` `    ``}`   `    ``// Adds a child and sibling to the node` `    ``public` `void` `addChild(HeapNode node) {` `        ``if` `(leftChild == ``null``)` `            ``leftChild = node;` `        ``else` `{` `            ``node.nextSibling = leftChild;` `            ``leftChild = node;` `        ``}` `    ``}` `}`   `// Pairing Heap implementation` `class` `PairingHeap {` `    ``HeapNode root;`   `    ``public` `PairingHeap() {` `        ``root = ``null``;` `    ``}`   `    ``public` `boolean` `isEmpty() {` `        ``return` `root == ``null``;` `    ``}`   `    ``public` `int` `top() {` `        ``return` `root.key;` `    ``}`   `    ``public` `void` `insert(``int` `key) {` `        ``root = insert(root, key);` `    ``}`   `    ``public` `void` `delete() {` `        ``root = delete(root);` `    ``}`   `    ``public` `void` `join(PairingHeap other) {` `        ``root = merge(root, other.root);` `    ``}`   `    ``// Helper functions` `    ``private` `HeapNode insert(HeapNode node, ``int` `key) {` `        ``return` `merge(node, ``new` `HeapNode(key, ``null``, ``null``));` `    ``}`   `    ``private` `HeapNode delete(HeapNode node) {` `        ``return` `twoPassMerge(node.leftChild);` `    ``}`   `    ``private` `HeapNode merge(HeapNode a, HeapNode b) {` `        ``// If any of the two nodes is null,` `        ``// 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;` `        ``}` `    ``}`   `    ``private` `HeapNode 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));` `        ``}` `    ``}`   `}`   `// Driver code` `public` `class` `Main {` `    ``public` `static` `void` `main(String[] args) {`   `        ``PairingHeap heap1 = ``new` `PairingHeap();` `        ``PairingHeap heap2 = ``new` `PairingHeap();`   `        ``heap2.insert(``5``);` `        ``heap2.insert(``2``);` `        ``heap2.insert(``6``);`   `        ``heap1.insert(``1``);` `        ``heap1.insert(``3``);` `        ``heap1.insert(``4``);`   `        ``heap1.join(heap2);`   `        ``System.out.println(heap1.top());` `        ``heap1.delete();`   `        ``System.out.println(heap1.top());` `        ``System.out.println(heap1.isEmpty() ? ``"True"` `: ``"False"``);` `    ``}` `}`   `// Contributed by adityasharmadev01`

## Python3

 `# Heap structure` `class` `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 heap` `def` `Insert(node, key):` `    ``return` `Merge(node, HeapNode(key,))`     `# This method is used when we want to delete root node` `def` `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 heap` `def` `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 Code` `if` `__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`

## Javascript

 `// Heap structure` `class HeapNode {` `  ``constructor(key, leftChild, nextSibling) {` `    ``this``.key = key;` `    ``this``.leftChild = leftChild || ``null``;` `    ``this``.nextSibling = nextSibling || ``null``;` `  ``}`   `  ``// Adds a child and sibling to the node` `  ``addChild(node) {` `    ``if` `(``this``.leftChild === ``null``) {` `      ``this``.leftChild = node;` `    ``} ``else` `{` `      ``node.nextSibling = ``this``.leftChild;` `      ``this``.leftChild = node;` `    ``}` `  ``}` `}`   `// Returns true if root of the tree` `// is null otherwise returns false` `function` `Empty(node) {` `  ``return` `node === ``null``;` `}`   `// Function to merge two heaps` `function` `Merge(A, 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;` `  ``}` `}`   `// Returns the root value of the heap` `function` `Top(node) {` `  ``return` `node.key;` `}`   `// Function to insert the new node in the heap` `function` `Insert(node, key) {` `  ``return` `Merge(node, ``new` `HeapNode(key, ``null``, ``null``));` `}`   `// This method is used when we want to delete root node` `function` `TwoPassMerge(node) {` `  ``if` `(node === ``null` `|| node.nextSibling === ``null``) {` `    ``return` `node;` `  ``} ``else` `{` `    ``let A = node;` `    ``let B = node.nextSibling;` `    ``let newNode = node.nextSibling.nextSibling;`   `    ``A.nextSibling = ``null``;` `    ``B.nextSibling = ``null``;`   `    ``return` `Merge(Merge(A, B), TwoPassMerge(newNode));` `  ``}` `}`   `// Function to delete the root node in heap` `function` `Delete(node) {` `  ``return` `TwoPassMerge(node.leftChild);` `}`   `class PairingHeap {` `  ``constructor() {` `    ``this``.root = ``null``;` `  ``}`   `  ``empty() {` `    ``return` `Empty(``this``.root);` `  ``}`   `  ``top() {` `    ``return` `Top(``this``.root);` `  ``}`   `  ``insert(key) {` `    ``this``.root = Insert(``this``.root, key);` `  ``}`   `  ``delete``() {` `    ``this``.root = Delete(``this``.root);` `  ``}`   `  ``join(other) {` `    ``this``.root = Merge(``this``.root, other.root);` `  ``}` `}`   `// Driver Code` `const heap1 = ``new` `PairingHeap();` `const heap2 = ``new` `PairingHeap();` `heap2.insert(5);` `heap2.insert(2);` `heap2.insert(6);` `heap1.insert(1);` `heap1.insert(3);` `heap1.insert(4);` `heap1.join(heap2);` `console.log(heap1.top());` `heap1.``delete``();` `console.log(heap1.top());` `console.log(heap1.empty() ? ``"True"` `: ``"False"``);`

Output:

```1
2
False```

Time Complexity:
Insertion: O(1)
Merge: O(1)
Deletion: O(logN)
Auxiliary Space: O(1).

My Personal Notes arrow_drop_up