Given a Binary Search Tree, convert it into a Min-Heap containing the same elements in O(n) time. Do this in-place.
Input: Binary Search Tree
8
/ \
4 12
/ \ / \
2 6 10 14
Output - Min Heap
2
/ \
4 6
/ \ / \
8 10 12 14
[Or any other tree that follows Min Heap
properties and has same keys]
If we are allowed to use extra space, we can perform inorder traversal of the tree and store the keys in an auxiliary array. As we’re doing inorder traversal on a BST, array will be sorted. Finally, we construct a complete binary tree from the sorted array. We construct the binary tree level by level and from left to right by taking next minimum element from sorted array. The constructed binary tree will be a min-Heap. This solution works in O(n) time, but is not in-place.
How to do it in-place?
The idea is to convert the binary search tree into a sorted linked list first. We can do this by traversing the BST in inorder fashion. We add nodes at the beginning of current linked list and update head of the list using pointer to head pointer. Since we insert at the beginning, to maintain sorted order, we first traverse the right subtree before the left subtree. i.e. do a reverse inorder traversal.
Finally we convert the sorted linked list into a min-Heap by setting the left and right pointers appropriately. We can do this by doing a Level order traversal of the partially built Min-Heap Tree using queue and traversing the linked list at the same time. At every step, we take the parent node from queue, make next two nodes of linked list as children of the parent node, and enqueue the next two nodes to queue. As the linked list is sorted, the min-heap property is maintained.
Below is the implementation of above idea:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int data;
Node *left, *right;
};
Node* newNode( int data)
{
Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return node;
}
void printLevelOrder(Node *root)
{
if (root == NULL) return ;
queue<Node *> q;
q.push(root);
while (!q.empty())
{
int nodeCount = q.size();
while (nodeCount > 0)
{
Node *node = q.front();
cout << node->data << " " ;
q.pop();
if (node->left)
q.push(node->left);
if (node->right)
q.push(node->right);
nodeCount--;
}
cout << endl;
}
}
void BSTToSortedLL(Node* root, Node** head_ref)
{
if (root == NULL)
return ;
BSTToSortedLL(root->right, head_ref);
root->right = *head_ref;
if (*head_ref != NULL)
(*head_ref)->left = NULL;
*head_ref = root;
BSTToSortedLL(root->left, head_ref);
}
void SortedLLToMinHeap(Node* &root, Node* head)
{
if (head == NULL)
return ;
queue<Node *> q;
root = head;
head = head->right;
root->right = NULL;
q.push(root);
while (head)
{
Node* parent = q.front();
q.pop();
Node *leftChild = head;
head = head->right;
leftChild->right = NULL;
q.push(leftChild);
parent->left = leftChild;
if (head)
{
Node *rightChild = head;
head = head->right;
rightChild->right = NULL;
q.push(rightChild);
parent->right = rightChild;
}
}
}
Node* BSTToMinHeap(Node* &root)
{
Node *head = NULL;
BSTToSortedLL(root, &head);
root = NULL;
SortedLLToMinHeap(root, head);
}
int main()
{
Node* root = newNode(8);
root->left = newNode(4);
root->right = newNode(12);
root->right->left = newNode(10);
root->right->right = newNode(14);
root->left->left = newNode(2);
root->left->right = newNode(6);
BSTToMinHeap(root);
printLevelOrder(root);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static class Node
{
int data;
Node left, right;
};
static Node newNode( int data)
{
Node node = new Node();
node.data = data;
node.left = node.right = null ;
return node;
}
static void printLevelOrder(Node root)
{
if (root == null ) return ;
Queue<Node> q = new LinkedList<>();
q.add(root);
while (q.size() > 0 )
{
int nodeCount = q.size();
while (nodeCount > 0 )
{
Node node = q.peek();
System.out.print( node.data + " " );
q.remove();
if (node.left != null )
q.add(node.left);
if (node.right != null )
q.add(node.right);
nodeCount--;
}
System.out.println();
}
}
static Node BSTToSortedLL(Node root, Node head_ref)
{
if (root == null )
return head_ref;
head_ref = BSTToSortedLL(root.right, head_ref);
root.right = head_ref;
if (head_ref != null )
(head_ref).left = null ;
head_ref = root;
head_ref = BSTToSortedLL(root.left, head_ref);
return head_ref;
}
static Node SortedLLToMinHeap(Node root, Node head)
{
if (head == null )
return null ;
Queue<Node > q = new LinkedList<>();
root = head;
head = head.right;
root.right = null ;
q.add(root);
while (head != null )
{
Node parent = q.peek();
q.remove();
Node leftChild = head;
head = head.right;
leftChild.right = null ;
q.add(leftChild);
parent.left = leftChild;
if (head != null )
{
Node rightChild = head;
head = head.right;
rightChild.right = null ;
q.add(rightChild);
parent.right = rightChild;
}
}
return root;
}
static Node BSTToMinHeap(Node root)
{
Node head = null ;
head = BSTToSortedLL(root, head);
root = null ;
root = SortedLLToMinHeap(root, head);
return root;
}
public static void main(String args[])
{
Node root = newNode( 8 );
root.left = newNode( 4 );
root.right = newNode( 12 );
root.right.left = newNode( 10 );
root.right.right = newNode( 14 );
root.left.left = newNode( 2 );
root.left.right = newNode( 6 );
root = BSTToMinHeap(root);
printLevelOrder(root);
}
}
|
Python3
class newNode:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def printLevelOrder(root):
if (root = = None ):
return
q = []
q.append(root)
while ( len (q)):
nodeCount = len (q)
while (nodeCount > 0 ) :
node = q[ 0 ]
print (node.data, end = " " )
q.pop( 0 )
if (node.left) :
q.append(node.left)
if (node.right) :
q.append(node.right)
nodeCount - = 1
print ()
def BSTToSortedLL(root, head_ref):
if (root = = None ) :
return
BSTToSortedLL(root.right, head_ref)
root.right = head_ref[ 0 ]
if (head_ref[ 0 ] ! = None ):
(head_ref[ 0 ]).left = None
head_ref[ 0 ] = root
BSTToSortedLL(root.left, head_ref)
def SortedLLToMinHeap( root, head) :
if (head = = None ) :
return
q = []
root[ 0 ] = head[ 0 ]
head[ 0 ] = head[ 0 ].right
root[ 0 ].right = None
q.append(root[ 0 ])
while (head[ 0 ] ! = None ) :
parent = q[ 0 ]
q.pop( 0 )
leftChild = head[ 0 ]
head[ 0 ] = head[ 0 ].right
leftChild.right = None
q.append(leftChild)
parent.left = leftChild
if (head) :
rightChild = head[ 0 ]
head[ 0 ] = head[ 0 ].right
rightChild.right = None
q.append(rightChild)
parent.right = rightChild
def BSTToMinHeap(root):
head = [ None ]
BSTToSortedLL(root, head)
root = [ None ]
SortedLLToMinHeap(root, head)
return root
if __name__ = = '__main__' :
root = newNode( 8 )
root.left = newNode( 4 )
root.right = newNode( 12 )
root.right.left = newNode( 10 )
root.right.right = newNode( 14 )
root.left.left = newNode( 2 )
root.left.right = newNode( 6 )
root = BSTToMinHeap(root)
printLevelOrder( * root)
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
public
class Node
{
public
int data;
public
Node left, right;
};
static Node newNode( int data)
{
Node node = new Node();
node.data = data;
node.left = node.right = null ;
return node;
}
static void printLevelOrder(Node root)
{
if (root == null ) return ;
Queue<Node> q = new Queue<Node>();
q.Enqueue(root);
while (q.Count > 0)
{
int nodeCount = q.Count;
while (nodeCount > 0)
{
Node node = q.Peek();
Console.Write( node.data + " " );
q.Dequeue();
if (node.left != null )
q.Enqueue(node.left);
if (node.right != null )
q.Enqueue(node.right);
nodeCount--;
}
Console.WriteLine();
}
}
static Node BSTToSortedLL(Node root, Node head_ref)
{
if (root == null )
return head_ref;
head_ref = BSTToSortedLL(root.right, head_ref);
root.right = head_ref;
if (head_ref != null )
(head_ref).left = null ;
head_ref = root;
head_ref = BSTToSortedLL(root.left, head_ref);
return head_ref;
}
static Node SortedLLToMinHeap(Node root, Node head)
{
if (head == null )
return null ;
Queue<Node > q = new Queue<Node>();
root = head;
head = head.right;
root.right = null ;
q.Enqueue(root);
while (head != null )
{
Node parent = q.Peek();
q.Dequeue();
Node leftChild = head;
head = head.right;
leftChild.right = null ;
q.Enqueue(leftChild);
parent.left = leftChild;
if (head != null )
{
Node rightChild = head;
head = head.right;
rightChild.right = null ;
q.Enqueue(rightChild);
parent.right = rightChild;
}
}
return root;
}
static Node BSTToMinHeap(Node root)
{
Node head = null ;
head = BSTToSortedLL(root, head);
root = null ;
root = SortedLLToMinHeap(root, head);
return root;
}
public static void Main(String []args)
{
Node root = newNode(8);
root.left = newNode(4);
root.right = newNode(12);
root.right.left = newNode(10);
root.right.right = newNode(14);
root.left.left = newNode(2);
root.left.right = newNode(6);
root = BSTToMinHeap(root);
printLevelOrder(root);
}
}
|
Javascript
<script>
class Node
{
constructor()
{
this .data = 0;
this .left = null ;
this .right = null ;
}
};
function newNode(data)
{
var node = new Node();
node.data = data;
node.left = node.right = null ;
return node;
}
function printLevelOrder(root)
{
if (root == null ) return ;
var q = [];
q.push(root);
while (q.length > 0)
{
var nodeCount = q.length;
while (nodeCount > 0)
{
var node = q[0];
document.write( node.data + " " );
q.shift();
if (node.left != null )
q.push(node.left);
if (node.right != null )
q.push(node.right);
nodeCount--;
}
document.write( "<br>" );
}
}
function BSTToSortedLL(root, head_ref)
{
if (root == null )
return head_ref;
head_ref = BSTToSortedLL(root.right, head_ref);
root.right = head_ref;
if (head_ref != null )
(head_ref).left = null ;
head_ref = root;
head_ref = BSTToSortedLL(root.left, head_ref);
return head_ref;
}
function SortedLLToMinHeap( root, head)
{
if (head == null )
return null ;
var q = [];
root = head;
head = head.right;
root.right = null ;
q.push(root);
while (head != null )
{
var parent = q[0];
q.shift();
var leftChild = head;
head = head.right;
leftChild.right = null ;
q.push(leftChild);
parent.left = leftChild;
if (head != null )
{
var rightChild = head;
head = head.right;
rightChild.right = null ;
q.push(rightChild);
parent.right = rightChild;
}
}
return root;
}
function BSTToMinHeap(root)
{
var head = null ;
head = BSTToSortedLL(root, head);
root = null ;
root = SortedLLToMinHeap(root, head);
return root;
}
var root = newNode(8);
root.left = newNode(4);
root.right = newNode(12);
root.right.left = newNode(10);
root.right.right = newNode(14);
root.left.left = newNode(2);
root.left.right = newNode(6);
root = BSTToMinHeap(root);
printLevelOrder(root);
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
01 Jul, 2022
Like Article
Save Article