Given two Binary Search Trees(BST), print the elements of both BSTs in sorted form.
Note: Both the BSTs will not have any common element.
Examples:
Input
First BST:
3
/ \
1 5
Second BST:
4
/ \
2 6
Output: 1 2 3 4 5 6
Input:
First BST:
8
/ \
2 10
/
1
Second BST:
5
/
3
/
0
Output: 0 1 2 3 5 8 10
The idea is to use the fact the leftmost element (first in inorder traversal) of the tree is the least element in a BST. So we compute this value for both the trees and print the smaller one, now we delete this printed element from the respective tree and update it. Then we recursively call our function with the updated tree. We do this until one of the trees is exhausted. Now we simply print the inorder traversal of the other tree.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Node {
public :
int data;
Node* left;
Node* right;
Node( int x)
{
data = x;
left = right = NULL;
}
};
void inorder(Node* root)
{
if (root != NULL) {
inorder(root->left);
cout << root->data << " " ;
inorder(root->right);
}
}
void merge(Node* root1, Node* root2)
{
if (!root1 && !root2)
return ;
if (!root1) {
inorder(root2);
return ;
}
if (!root2) {
inorder(root1);
return ;
}
Node* temp1 = root1;
Node* prev1 = NULL;
while (temp1->left) {
prev1 = temp1;
temp1 = temp1->left;
}
Node* temp2 = root2;
Node* prev2 = NULL;
while (temp2->left) {
prev2 = temp2;
temp2 = temp2->left;
}
if (temp1->data <= temp2->data) {
cout << temp1->data << " " ;
if (prev1 == NULL) {
merge(root1->right, root2);
}
else {
prev1->left = temp1->right;
merge(root1, root2);
}
}
else {
cout << temp2->data << " " ;
if (prev2 == NULL) {
merge(root1, root2->right);
}
else {
prev2->left = temp2->right;
merge(root1, root2);
}
}
}
int main()
{
Node *root1 = NULL, *root2 = NULL;
root1 = new Node(3);
root1->left = new Node(1);
root1->right = new Node(5);
root2 = new Node(4);
root2->left = new Node(2);
root2->right = new Node(6);
merge(root1, root2);
return 0;
}
|
Java
import java.util.*;
class GFG{
static class Node
{
int data;
Node left;
Node right;
};
static Node newNode( int num)
{
Node temp = new Node();
temp.data = num;
temp.left = temp.right = null ;
return temp;
}
static void inorder(Node root)
{
if (root != null )
{
inorder(root.left);
System.out.print(root.data + " " );
inorder(root.right);
}
}
static void merge(Node root1, Node root2)
{
if (root1 == null && root2 == null )
return ;
if (root1 == null )
{
inorder(root2);
return ;
}
if (root2 == null )
{
inorder(root1);
return ;
}
Node temp1 = root1;
Node prev1 = null ;
while (temp1.left != null )
{
prev1 = temp1;
temp1 = temp1.left;
}
Node temp2 = root2;
Node prev2 = null ;
while (temp2.left != null )
{
prev2 = temp2;
temp2 = temp2.left;
}
if (temp1.data <= temp2.data)
{
System.out.print(temp1.data + " " );
if (prev1 == null )
{
merge(root1.right, root2);
}
else
{
prev1.left = temp1.right;
merge(root1, root2);
}
}
else
{
System.out.print(temp2.data + " " );
if (prev2 == null )
{
merge(root1, root2.right);
}
else
{
prev2.left = temp2.right;
merge(root1, root2);
}
}
}
public static void main(String args[])
{
Node root1 = null , root2 = null ;
root1 = newNode( 3 );
root1.left = newNode( 1 );
root1.right = newNode( 5 );
root2 = newNode( 4 );
root2.left = newNode( 2 );
root2.right = newNode( 6 );
merge(root1, root2);
}
}
|
Python3
class node:
def __init__ ( self , key):
self .data = key
self .left = None
self .right = None
def inorder(root):
if (root ! = None ):
inorder(root.left)
print (root.data, end = " " )
inorder(root.right)
def merge(root1, root2):
if ( not root1 and not root2):
return
if ( not root1):
inorder(root2)
return
if ( not root2):
inorder(root1)
return
temp1 = root1
prev1 = None
while (temp1.left):
prev1 = temp1
temp1 = temp1.left
temp2 = root2
prev2 = None
while (temp2.left):
prev2 = temp2
temp2 = temp2.left
if (temp1.data < = temp2.data):
print (temp1.data, end = " " )
if (prev1 = = None ):
merge(root1.right, root2)
else :
prev1.left = temp1.right
merge(root1, root2)
else :
print (temp2.data, end = " " )
if (prev2 = = None ):
merge(root1, root2.right)
else :
prev2.left = temp2.right
merge(root1, root2)
if __name__ = = '__main__' :
root1 = None
root2 = None
root1 = node( 3 )
root1.left = node( 1 )
root1.right = node( 5 )
root2 = node( 4 )
root2.left = node( 2 )
root2.right = node( 6 )
merge(root1, root2)
|
C#
using System;
public class Node
{
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
class GFG{
static Node root1;
static Node root2;
static void inorder(Node root)
{
if (root != null )
{
inorder(root.left);
Console.WriteLine(root.data + " " );
inorder(root.right);
}
}
static void merge(Node root1, Node root2)
{
if (root1 == null && root2 == null )
{
return ;
}
if (root1 == null )
{
inorder(root2);
return ;
}
if (root2 == null )
{
inorder(root1);
return ;
}
Node temp1 = root1;
Node prev1 = null ;
while (temp1.left != null )
{
prev1 = temp1;
temp1 = temp1.left;
}
Node temp2 = root2;
Node prev2 = null ;
while (temp2.left != null )
{
prev2 = temp2;
temp2 = temp2.left;
}
if (temp1.data <= temp2.data)
{
Console.Write(temp1.data + " " );
if (prev1 == null )
{
merge(root1.right, root2);
}
else
{
prev1.left = temp1.right;
merge(root1, root2);
}
}
else
{
Console.Write(temp2.data + " " );
if (prev2 == null )
{
merge(root1, root2.right);
}
else
{
prev2.left = temp2.right;
merge(root1, root2);
}
}
}
static public void Main()
{
GFG.root1 = new Node(3);
GFG.root1.left = new Node(1);
GFG.root1.right = new Node(5);
GFG.root2 = new Node(4);
GFG.root2.left = new Node(2);
GFG.root2.right = new Node(6);
merge(root1, root2);
}
}
|
Javascript
<script>
class Node
{
constructor(num)
{
this .data=num;
this .left= this .right= null ;
}
}
function inorder(root)
{
if (root != null )
{
inorder(root.left);
document.write(root.data + " " );
inorder(root.right);
}
}
function merge(root1,root2)
{
if (root1 == null && root2 == null )
return ;
if (root1 == null )
{
inorder(root2);
return ;
}
if (root2 == null )
{
inorder(root1);
return ;
}
let temp1 = root1;
let prev1 = null ;
while (temp1.left != null )
{
prev1 = temp1;
temp1 = temp1.left;
}
let temp2 = root2;
let prev2 = null ;
while (temp2.left != null )
{
prev2 = temp2;
temp2 = temp2.left;
}
if (temp1.data <= temp2.data)
{
document.write(temp1.data + " " );
if (prev1 == null )
{
merge(root1.right, root2);
}
else
{
prev1.left = temp1.right;
merge(root1, root2);
}
}
else
{
document.write(temp2.data + " " );
if (prev2 == null )
{
merge(root1, root2.right);
}
else
{
prev2.left = temp2.right;
merge(root1, root2);
}
}
}
let root1 = null , root2 = null ;
root1 = new Node(3);
root1.left = new Node(1);
root1.right = new Node(5);
root2 = new Node(4);
root2.left = new Node(2);
root2.right = new Node(6);
merge(root1, root2);
</script>
|
Time Complexity: O((M+N)(h1+h2)), where M and N are the number of nodes of the two trees and, h1 and h2 are the heights of tree respectively.
Auxiliary Space: O(N)
Method 2: Using Morris Traversal of the trees
The above solution uses recursion and hence require O(N) auxiliary space. We can use the concept of Morris Traversal to improve the space complexity of the algorithm by eliminating the usage of stacks. Morris traversal is a method of traversing a binary tree without using recursion and with constant (O(1)) extra space.
The idea is to traverse to the smallest data node of both trees using Morris traversal and compare the nodes on both trees. We use the smaller one to add to the answer array and move it to the next node in sorted order. We know that inorder traversal of Binary Search Trees is in the sorted order. Thus we can move to the smallest node and continue moving in the inorder order to get to the next higher node.
Algorithm:
- Apply Morris traversal on root1:
- Check if root has a left node and if it has a left node.
- Go to the rightmost node of the left node.
- On the right most node of the left, assign its right pointer to root.
- Make left = root->left and make root->left = NULL
- Move root to left.
- Repeat till root has a left node
- If it doesn’t have a left node, that means root is the smallest node, thus break root1’s Morris traversal.
- Apply same Morris traversal for root2.
- Now root1 and root2 are at the smallest nodes of their respective trees. Compare root1 data with root2 data:
- If root1 data is smaller than or equal to root2 data: add root1 data to our answer array and move root1 to its right.
- Else add root2 data to our answer array and move root2 to its right.
- If in step 3, root1 or root2 is NULL, that means that tree is exhausted and we have added all nodes to answer array, so we just add the remaining tree data to answer array without comparison and move it to its right.
- Repeat steps 1 to 4 until both trees are exhausted.
C++
#include <bits/stdc++.h>
using namespace std;
class Node {
public :
int data;
Node *left, *right;
Node( int data){
this ->data = data;
this ->left = NULL;
this ->right = NULL;
}
};
void mergeBSTs(Node*, Node*);
int main(){
Node* root1 = new Node(3);
root1->left = new Node(1);
root1->right = new Node(5);
Node* root2 = new Node(4);
root2->left = new Node(2);
root2->right = new Node(6);
mergeBSTs(root1, root2);
}
void mergeBSTs(Node* root1, Node* root2){
while (root1 || root2) {
while (root1) {
if (root1->left) {
Node* left = root1->left;
while (left->right)
left = left->right;
left->right = root1;
left = root1->left;
root1->left = NULL;
root1 = left;
}
else break ;
}
while (root2) {
if (root2->left) {
Node* left = root2->left;
while (left->right)
left = left->right;
left->right = root2;
left = root2->left;
root2->left = NULL;
root2 = left;
}
else break ;
}
if (root1 && root2) {
if (root1->data <= root2->data) {
cout << root1->data << " " ;
root1 = root1->right;
}
else {
cout << root2->data << " " ;
root2 = root2->right;
}
}
else if (root1) {
cout << root1->data << " " ;
root1 = root1->right;
}
else if (root2) {
cout << root2->data << " " ;
root2 = root2->right;
}
}
}
|
Java
import java.util.*;
class GFG{
static class Node {
int data;
Node left, right;
Node( int data){
this .data = data;
this .left = null ;
this .right = null ;
}
};
public static void main(String[] args){
Node root1 = new Node( 3 );
root1.left = new Node( 1 );
root1.right = new Node( 5 );
Node root2 = new Node( 4 );
root2.left = new Node( 2 );
root2.right = new Node( 6 );
mergeBSTs(root1, root2);
}
static void mergeBSTs(Node root1, Node root2)
{
while (root1 != null || root2 != null )
{
while (root1 != null )
{
if (root1.left != null )
{
Node left = root1.left;
while (left.right != null )
left = left.right;
left.right = root1;
left = root1.left;
root1.left = null ;
root1 = left;
}
else break ;
}
while (root2!= null ) {
if (root2.left!= null ) {
Node left = root2.left;
while (left.right!= null )
left = left.right;
left.right = root2;
left = root2.left;
root2.left = null ;
root2 = left;
}
else break ;
}
if (root1!= null && root2!= null ) {
if (root1.data <= root2.data) {
System.out.print(root1.data+ " " );
root1 = root1.right;
}
else {
System.out.print(root2.data+ " " );
root2 = root2.right;
}
}
else if (root1 != null ) {
System.out.print(root1.data+ " " );
root1 = root1.right;
}
else if (root2 != null ) {
System.out.print(root2.data+ " " );
root2 = root2.right;
}
}
}
}
|
Python3
class node:
def __init__( self , key):
self .data = key
self .left = None
self .right = None
def mergeBSTs(root1, root2):
while (root1 or root2):
while (root1):
if (root1.left):
left = root1.left
while (left.right):
left = left.right
left.right = root1
left = root1.left
root1.left = None
root1 = left
else :
break
while (root2):
if (root2.left):
left = root2.left
while (left.right):
left = left.right
left.right = root2
left = root2.left
root2.left = None
root2 = left
else :
break
if (root1 and root2):
if (root1.data < = root2.data):
print (root1.data, end = " " )
root1 = root1.right
else :
print (root2.data, end = " " )
root2 = root2.right
elif (root1):
print (root1.data, end = " " )
root1 = root1.right
elif (root2):
print (root2.data, end = " " )
root2 = root2.right
if __name__ = = '__main__' :
root1 = None
root2 = None
root1 = node( 3 )
root1.left = node( 1 )
root1.right = node( 5 )
root2 = node( 4 )
root2.left = node( 2 )
root2.right = node( 6 )
mergeBSTs(root1, root2)
|
C#
using System;
public class GFG {
public class Node {
public int data;
public Node left, right;
public Node( int data) {
this .data = data;
this .left = null ;
this .right = null ;
}
};
public static void Main(String[] args) {
Node root1 = new Node(3);
root1.left = new Node(1);
root1.right = new Node(5);
Node root2 = new Node(4);
root2.left = new Node(2);
root2.right = new Node(6);
mergeBSTs(root1, root2);
}
static void mergeBSTs(Node root1, Node root2) {
while (root1 != null || root2 != null ) {
while (root1 != null ) {
if (root1.left != null ) {
Node left = root1.left;
while (left.right != null )
left = left.right;
left.right = root1;
left = root1.left;
root1.left = null ;
root1 = left;
} else
break ;
}
while (root2 != null )
{
if (root2.left != null ) {
Node left = root2.left;
while (left.right != null )
left = left.right;
left.right = root2;
left = root2.left;
root2.left = null ;
root2 = left;
} else
break ;
}
if (root1 != null && root2 != null )
{
if (root1.data <= root2.data) {
Console.Write(root1.data + " " );
root1 = root1.right;
} else {
Console.Write(root2.data + " " );
root2 = root2.right;
}
} else if (root1 != null )
{
Console.Write(root1.data + " " );
root1 = root1.right;
} else if (root2 != null )
{
Console.Write(root2.data + " " );
root2 = root2.right;
}
}
}
}
|
Javascript
<script>
class Node
{
constructor(data) {
this .data = data;
this .left = null ;
this .right = null ;
}
}
function mergeBSTs(root1, root2)
{
while (root1 != null || root2 != null ) {
while (root1 != null ) {
if (root1.left != null ) {
var left = root1.left;
while (left.right != null )
left = left.right;
left.right = root1;
left = root1.left;
root1.left = null ;
root1 = left;
} else
break ;
}
while (root2 != null ) {
if (root2.left != null ) {
var left = root2.left;
while (left.right != null )
left = left.right;
left.right = root2;
left = root2.left;
root2.left = null ;
root2 = left;
} else
break ;
}
if (root1 != null && root2 != null ) {
if (root1.data <= root2.data) {
document.write(root1.data + " " );
root1 = root1.right;
} else {
document.write(root2.data + " " );
root2 = root2.right;
}
} else if (root1 != null ) {
document.write(root1.data + " " );
root1 = root1.right;
} else if (root2 != null ) {
document.write(root2.data + " " );
root2 = root2.right;
}
}
}
var root1 = new Node(3);
root1.left = new Node(1);
root1.right = new Node(5);
var root2 = new Node(4);
root2.left = new Node(2);
root2.right = new Node(6);
mergeBSTs(root1, root2);
</script>
|
Time Complexity: O(m + n)
Auxiliary Space Complexity: O(1).
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
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!