# Skew Heap

A skew heap (or self – adjusting heap) is a heap data structure implemented as a binary tree. Skew heaps are advantageous because of their ability to merge more quickly than binary heaps. In contrast with binary heaps, there are no structural constraints, so there is no guarantee that the height of the tree is logarithmic. Only two conditions must be satisfied :

1. The general heap order must be there (root is minimum and same is recursively true for subtrees), but balanced property (all levels must be full except the last) is not required.
2. Main operation in Skew Heaps is Merge. We can implement other operations like insert, extractMin(), etc using Merge only.

Example :
1. Consider the skew heap 1 to be

2. The second heap to be considered

4. And we obtain the final merged tree as

Recursive Merge Process :
merge(h1, h2)

1. Let h1 and h2 be the two min skew heaps to be merged. Let h1’s root be smaller than h2’s root (If not smaller, we can swap to get the same).
2. We swap h1->left and h1->right.
3. h1->left = merge(h2, h1->left)

Examples :

```Let h1 be
10
/    \
20      30
/        /
40        50

Let h2 be
15
/    \
25      35
/  \
45    55

After swapping h1->left and h1->right, we get
10
/    \
30      20
/        /
50        40

Now we recursively Merge
30
/     AND
50

15
/    \
25      35
/  \
45    55
After recursive merge, we get (Please do it
using pen and paper).
15
/     \
30        25
/  \     /    \
35    50  45    55

We make this merged tree as left of original
h1 and we get following result.
10
/         \
15           20
/      \       /
30       25    40
/   \    /    \
35   40  45    55```

For visualization : https://www.cs.usfca.edu/~galles/JavascriptVisual/LeftistHeap.html

Implementation:

## CPP

 `// CPP program to implement Skew Heap``// operations.``#include ``using` `namespace` `std;` `struct` `SkewHeap``{``    ``int` `key;``    ``SkewHeap* right;``    ``SkewHeap* left;` `    ``// constructor to make a new``    ``// node of heap``    ``SkewHeap()``    ``{``        ``key = 0;``        ``right = NULL;``        ``left = NULL;``    ``}` `    ``// the special merge function that's``    ``// used in most of the other operations``    ``// also``    ``SkewHeap* merge(SkewHeap* h1, SkewHeap* h2)``    ``{``        ``// If one of the heaps is empty``        ``if` `(h1 == NULL)``            ``return` `h2;``        ``if` `(h2 == NULL)``            ``return` `h1;` `        ``// Make sure that h1 has smaller``        ``// key.``        ``if` `(h1->key > h2->key)``           ``swap(h1, h2);` `        ``// Swap h1->left and h1->right``        ``swap(h1->left, h1->right);` `        ``// Merge h2 and h1->left and make``        ``// merged tree as left of h1.``        ``h1->left = merge(h2, h1->left);` `        ``return` `h1;``    ``}` `    ``// function to construct heap using``    ``// values in the array``    ``SkewHeap* construct(SkewHeap* root,``                     ``int` `heap[], ``int` `n)``    ``{``        ``SkewHeap* temp;``        ``for` `(``int` `i = 0; i < n; i++) {``            ``temp = ``new` `SkewHeap;``            ``temp->key = heap[i];``            ``root = merge(root, temp);``        ``}``        ``return` `root;``    ``}` `    ``// function to print the Skew Heap,``    ``// as it is in form of a tree so we use``    ``// tree traversal algorithms``    ``void` `inorder(SkewHeap* root)``    ``{``        ``if` `(root == NULL)``            ``return``;``        ``else` `{``            ``inorder(root->left);``            ``cout << root->key << ``"  "``;``            ``inorder(root->right);``        ``}``        ``return``;``    ``}``};` `// Driver Code``int` `main()``{``    ``// Construct two heaps``    ``SkewHeap heap, *temp1 = NULL,``                   ``*temp2 = NULL;``    ``/*``            ``5``           ``/ \``          ``/   \``         ``10   12    */``    ``int` `heap1[] = { 12, 5, 10 };``    ``/*``            ``3``           ``/ \``          ``/   \``         ``7     8``        ``/``       ``/``      ``14    */``    ``int` `heap2[] = { 3, 7, 8, 14 };``    ``int` `n1 = ``sizeof``(heap1) / ``sizeof``(heap1[0]);``    ``int` `n2 = ``sizeof``(heap2) / ``sizeof``(heap2[0]);``    ``temp1 = heap.construct(temp1, heap1, n1);``    ``temp2 = heap.construct(temp2, heap2, n2);` `    ``// Merge two heaps``    ``temp1 = heap.merge(temp1, temp2);``    ``/*``            ``3``           ``/ \``          ``/   \``         ``5     7``        ``/ \   /``       ``8  10 14``      ``/``     ``12    */``    ``cout << ``"Merged Heap is: "` `<< endl;``    ``heap.inorder(temp1);``}`

## Java

 `// Java program to implement Skew Heap operations.``import` `java.util.*;` `class` `SkewHeap {``    ``int` `key;``    ``SkewHeap right;``    ``SkewHeap left;` `    ``// constructor to make a new``    ``// node of heap``    ``SkewHeap()``    ``{``        ``key = ``0``;``        ``right = ``null``;``        ``left = ``null``;``    ``}` `    ``// the special merge function that's``    ``// used in most of the other operations``    ``// also``    ``SkewHeap merge(SkewHeap h1, SkewHeap h2)``    ``{``        ``// If one of the heaps is empty``        ``if` `(h1 == ``null``)``            ``return` `h2;``        ``if` `(h2 == ``null``)``            ``return` `h1;` `        ``// Make sure that h1 has smaller``        ``// key.``        ``if` `(h1.key > h2.key) {``            ``SkewHeap temp = h1;``            ``h1 = h2;``            ``h2 = temp;``        ``}` `        ``// Swap h1.left and h1.right``        ``SkewHeap temp = h1.left;``        ``h1.left = h1.right;``        ``h1.right = temp;` `        ``// Merge h2 and h1.left and make``        ``// merged tree as left of h1.``        ``h1.left = merge(h2, h1.left);` `        ``return` `h1;``    ``}` `    ``// function to construct heap using``    ``// values in the array``    ``SkewHeap construct(SkewHeap root, ``int``[] heap, ``int` `n)``    ``{``        ``SkewHeap temp;``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``temp = ``new` `SkewHeap();``            ``temp.key = heap[i];``            ``root = merge(root, temp);``        ``}``        ``return` `root;``    ``}` `    ``// function to print the Skew Heap,``    ``// as it is in form of a tree so we use``    ``// tree traversal algorithms``    ``void` `inorder(SkewHeap root)``    ``{``        ``if` `(root == ``null``)``            ``return``;``        ``else` `{``            ``inorder(root.left);``            ``System.out.print(root.key + ``"  "``);``            ``inorder(root.right);``        ``}``        ``return``;``    ``}``}` `// Driver Code``public` `class` `Main {``    ``public` `static` `void` `main(String[] args)``    ``{``        ``// Construct two heaps``        ``SkewHeap heap = ``new` `SkewHeap(), temp1 = ``null``,``                 ``temp2 = ``null``;``        ``/*``        ``5``        ``/``        ``/``        ``10 12 /``       ` `        ``/``        ``3``        ``/``        ``/``        ``7 8``        ``/``        ``/``        ``14 */``       ``int``[] heap1 = { ``12``, ``5``, ``10` `};``        ``int``[] heap2 = { ``3``, ``7``, ``8``, ``14` `};``        ``int` `n1 = heap1.length;``        ``int` `n2 = heap2.length;``        ``temp1 = heap.construct(temp1, heap1, n1);``        ``temp2 = heap.construct(temp2, heap2, n2);` `        ``// Merge two heaps``        ``temp1 = heap.merge(temp1, temp2);``        ``/*``            ``3``           ``/ \``          ``/   \``         ``5     7``        ``/ \   /``       ``8  10 14``      ``/``     ``12    */``        ``System.out.println(``"Merged Heap is: "``);``        ``heap.inorder(temp1);``    ``}``}`

## Python3

 `# Python code implementation` `class` `SkewHeap:``    ``def` `__init__(``self``):``        ``self``.key ``=` `0``        ``self``.right ``=` `None``        ``self``.left ``=` `None` `    ``# the special merge function that's used ``    ``# in most of the other operations also``    ``def` `merge(``self``, h1, h2):``        ``# If one of the heaps is empty``        ``if` `h1 ``is` `None``:``            ``return` `h2``        ``if` `h2 ``is` `None``:``            ``return` `h1` `        ``# Make sure that h1 has smaller key.``        ``if` `h1.key > h2.key:``            ``h1, h2 ``=` `h2, h1` `        ``# Swap h1.left and h1.right``        ``h1.left, h1.right ``=` `h1.right, h1.left` `        ``# Merge h2 and h1.left and make ``        ``# merged tree as left of h1.``        ``h1.left ``=` `self``.merge(h2, h1.left)` `        ``return` `h1` `    ``# function to construct heap using values in the array``    ``def` `construct(``self``, root, heap, n):``        ``for` `i ``in` `range``(n):``            ``temp ``=` `SkewHeap()``            ``temp.key ``=` `heap[i]``            ``root ``=` `self``.merge(root, temp)``        ``return` `root` `    ``# function to print the Skew Heap, as it is ``    ``# in form of a tree so we use``    ``# tree traversal algorithms``    ``def` `inorder(``self``, root):``        ``if` `root ``is` `None``:``            ``return``        ``else``:``            ``self``.inorder(root.left)``            ``print``(root.key, end``=``"  "``)``            ``self``.inorder(root.right)` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``    ``# Construct two heaps``    ``heap, temp1, temp2 ``=` `SkewHeap(), ``None``, ``None``    ``heap1 ``=` `[``12``, ``5``, ``10``]``    ``heap2 ``=` `[``3``, ``7``, ``8``, ``14``]``    ``n1 ``=` `len``(heap1)``    ``n2 ``=` `len``(heap2)``    ``temp1 ``=` `heap.construct(temp1, heap1, n1)``    ``temp2 ``=` `heap.construct(temp2, heap2, n2)` `    ``# Merge two heaps``    ``temp1 ``=` `heap.merge(temp1, temp2)` `    ``print``(``"The heap obtained after merging is:"``)``    ``heap.inorder(temp1)` `# This code is contributed by karthik.`

## C#

 `using` `System;` `class` `SkewHeap {``    ``int` `key;``    ``SkewHeap right;``    ``SkewHeap left;` `    ``// constructor to make a new``    ``// node of heap``    ``public` `SkewHeap()``    ``{``        ``key = 0;``        ``right = ``null``;``        ``left = ``null``;``    ``}` `    ``// the special merge function that's``    ``// used in most of the other operations``    ``// also``    ``public` `SkewHeap merge(SkewHeap h1, SkewHeap h2)``    ``{``        ``// If one of the heaps is empty``        ``if` `(h1 == ``null``)``            ``return` `h2;``        ``if` `(h2 == ``null``)``            ``return` `h1;` `        ``// Make sure that h1 has smaller``        ``// key.``        ``if` `(h1.key > h2.key) {``            ``SkewHeap temp = h1;``            ``h1 = h2;``            ``h2 = temp;``        ``}` `        ``// Swap h1.left and h1.right``        ``SkewHeap temp2 = h1.left;``        ``h1.left = h1.right;``        ``h1.right = temp2;` `        ``// Merge h2 and h1.left and make``        ``// merged tree as left of h1.``        ``h1.left = merge(h2, h1.left);` `        ``return` `h1;``    ``}` `    ``// function to construct heap using``    ``// values in the array``    ``public` `SkewHeap construct(SkewHeap root, ``int``[] heap,``                              ``int` `n)``    ``{``        ``SkewHeap temp;``        ``for` `(``int` `i = 0; i < n; i++) {``            ``temp = ``new` `SkewHeap();``            ``temp.key = heap[i];``            ``root = merge(root, temp);``        ``}``        ``return` `root;``    ``}` `    ``// function to print the Skew Heap,``    ``// as it is in form of a tree so we use``    ``// tree traversal algorithms``    ``public` `void` `inorder(SkewHeap root)``    ``{``        ``if` `(root == ``null``)``            ``return``;``        ``else` `{``            ``inorder(root.left);``            ``Console.Write(root.key + ``"  "``);``            ``inorder(root.right);``        ``}``        ``return``;``    ``}``}` `// Driver Code``class` `Program {``    ``static` `void` `Main(``string``[] args)``    ``{``        ``// Construct two heaps``        ``SkewHeap heap = ``new` `SkewHeap(), temp1 = ``null``,``                 ``temp2 = ``null``;``        ``/*``        ``5``        ``/``        ``/``        ``10 12 /`  `            ``/``            ``3``            ``/``            ``/``            ``7 8``            ``/``            ``/``            ``14 */``        ``int``[] heap1 = { 12, 5, 10 };``        ``int``[] heap2 = { 3, 7, 8, 14 };``        ``int` `n1 = heap1.Length;``        ``int` `n2 = heap2.Length;``        ``temp1 = heap.construct(temp1, heap1, n1);``        ``temp2 = heap.construct(temp2, heap2, n2);` `        ``// Merge two heaps``        ``temp1 = heap.merge(temp1, temp2);``        ``/*``            ``3``           ``/ \``          ``/   \``         ``5     7``        ``/ \   /``       ``8  10 14``      ``/``     ``12    */``        ``Console.WriteLine(``"Merged Heap is: "``);``        ``heap.inorder(temp1);``    ``}``}`

## Javascript

 `// JavaScript code implementation``class SkewHeap {``  ``constructor() {``    ``this``.key = 0;``    ``this``.right = ``null``;``    ``this``.left = ``null``;``  ``}` `  ``// the special merge function that's``  ``// used in most of the other operations``  ``// also``  ``merge(h1, h2) {``    ``// If one of the heaps is empty``    ``if` `(h1 == ``null``) ``return` `h2;``    ``if` `(h2 == ``null``) ``return` `h1;` `    ``// Make sure that h1 has smaller key.``    ``if` `(h1.key > h2.key) {``      ``[h1, h2] = [h2, h1];``    ``}` `    ``// Swap h1.left and h1.right``    ``[h1.left, h1.right] = [h1.right, h1.left];` `    ``// Merge h2 and h1.left and make merged tree as left of h1.``    ``h1.left = ``this``.merge(h2, h1.left);` `    ``return` `h1;``  ``}` `  ``// function to construct heap using values in the array``  ``construct(root, heap, n) {``    ``let temp;``    ``for` `(let i = 0; i < n; i++) {``      ``temp = ``new` `SkewHeap();``      ``temp.key = heap[i];``      ``root = ``this``.merge(root, temp);``    ``}``    ``return` `root;``  ``}` `  ``// function to print the Skew Heap,``  ``// as it is in form of a tree so we use``  ``// tree traversal algorithms``  ``inorder(root) {``    ``if` `(root == ``null``) ``return``;``    ``else` `{``      ``this``.inorder(root.left);``      ``console.log(root.key + ``"  "``);``      ``this``.inorder(root.right);``    ``}``    ``return``;``  ``}``}` `// Driver Code``// Construct two heaps``let heap = ``new` `SkewHeap(),``  ``temp1 = ``null``,``  ``temp2 = ``null``;` `let heap1 = [12, 5, 10];``let heap2 = [3, 7, 8, 14];``let n1 = heap1.length;``let n2 = heap2.length;``temp1 = heap.construct(temp1, heap1, n1);``temp2 = heap.construct(temp2, heap2, n2);` `// Merge two heaps``temp1 = heap.merge(temp1, temp2);` `console.log(``"The heap obtained after merging is:
"``);``heap.inorder(temp1);` `// This code is contributed by sankar.`

Output:
```The heap obtained after merging is:
12  8  5  10  3  14  7```

Time Complexity: O(NlogN)

Auxiliary Space: O(N)

Previous
Next