You are given two balanced binary search trees e.g., AVL or Red-Black Tree. Write a function that merges the two given balanced BSTs into a balanced binary search tree. Let there be m elements in the first tree and n elements in the other tree. Your merge function should take O(m+n) time.
In the following solutions, it is assumed that the sizes of trees are also given as input. If the size is not given, then we can get the size by traversing the tree (See this).
Method 1 (Insert elements of the first tree to the second):
Take all elements of the first BST one by one, and insert them into the second BST. Inserting an element to a self-balancing BST takes Logn time (See this) where n is the size of the BST. So time complexity of this method is Log(n) + Log(n+1) … Log(m+n-1). The value of this expression will be between mLogn and mLog(m+n-1). As an optimization, we can pick the smaller tree as the first tree.
Method 2 (Merge Inorder Traversals):
- Do inorder traversal of the first tree and store the traversal in one temp array arr1[]. This step takes O(m) time.Â
- Do inorder traversal of the second tree and store the traversal in another temp array arr2[]. This step takes O(n) time.Â
- The arrays created in steps 1 and 2 are sorted arrays. Merge the two sorted arrays into one array of size m + n. This step takes O(m+n) time.Â
- Construct a balanced tree from the merged array using the technique discussed in this post. This step takes O(m+n) time.
The time complexity of this method is O(m+n) which is better than method 1. This method takes O(m+n) time even if the input BSTs are not balanced.Â
Following is the implementation of this method.
C++
// C++ program to Merge Two Balanced Binary Search Trees #include<bits/stdc++.h>using namespace std;Â
/* A binary tree node has data, pointer to left child and a pointer to right child */class node { Â Â Â Â public:Â Â Â Â int data; Â Â Â Â node* left; Â Â Â Â node* right; }; Â
// A utility function to merge two sorted arrays into one int *merge(int arr1[], int arr2[], int m, int n); Â
// A helper function that stores inorder// traversal of a tree in inorder array void storeInorder(node* node, int inorder[],                            int *index_ptr); Â
/* A function that constructs BalancedBinary Search Tree from a sorted array node* sortedArrayToBST(int arr[], int start, int end); Â
/* This function merges two balanced BSTs with roots as root1 and root2. m and n are the sizes of the trees respectively */node* mergeTrees(node *root1, node *root2, int m, int n) {     // Store inorder traversal of     // first tree in an array arr1[]     int *arr1 = new int[m];     int i = 0;     storeInorder(root1, arr1, &i); Â
    // Store inorder traversal of second    // tree in another array arr2[]     int *arr2 = new int[n];     int j = 0;     storeInorder(root2, arr2, &j); Â
    // Merge the two sorted array into one     int *mergedArr = merge(arr1, arr2, m, n); Â
    // Construct a tree from the merged     // array and return root of the tree     return sortedArrayToBST (mergedArr, 0, m + n - 1); } Â
/* Helper function that allocatesa new node with the given data and NULL left and right pointers. */node* newNode(int data) { Â Â Â Â node* Node = new node();Â Â Â Â Node->data = data; Â Â Â Â Node->left = NULL; Â Â Â Â Node->right = NULL; Â
    return(Node); } Â
// A utility function to print inorder// traversal of a given binary tree void printInorder(node* node) { Â Â Â Â if (node == NULL) Â Â Â Â Â Â Â Â return; Â
    /* first recur on left child */    printInorder(node->left); Â
    cout << node->data << " "; Â
    /* now recur on right child */    printInorder(node->right); } Â
// A utility function to merge// two sorted arrays into one int *merge(int arr1[], int arr2[], int m, int n) {     // mergedArr[] is going to contain result     int *mergedArr = new int[m + n];     int i = 0, j = 0, k = 0; Â
    // Traverse through both arrays     while (i < m && j < n)     {         // Pick the smaller element and put it in mergedArr         if (arr1[i] < arr2[j])         {             mergedArr[k] = arr1[i];             i++;         }         else        {             mergedArr[k] = arr2[j];             j++;         }         k++;     } Â
    // If there are more elements in first array     while (i < m)     {         mergedArr[k] = arr1[i];         i++; k++;     } Â
    // If there are more elements in second array     while (j < n)     {         mergedArr[k] = arr2[j];         j++; k++;     } Â
    return mergedArr; } Â
// A helper function that stores inorder// traversal of a tree rooted with node void storeInorder(node* node, int inorder[], int *index_ptr) { Â Â Â Â if (node == NULL) Â Â Â Â Â Â Â Â return; Â
    /* first recur on left child */    storeInorder(node->left, inorder, index_ptr); Â
    inorder[*index_ptr] = node->data;     (*index_ptr)++; // increase index for next entry Â
    /* now recur on right child */    storeInorder(node->right, inorder, index_ptr); } Â
/* A function that constructs Balanced // Binary Search Tree from a sorted array node* sortedArrayToBST(int arr[], int start, int end) { Â Â Â Â /* Base Case */Â Â Â Â if (start > end) Â Â Â Â return NULL; Â
    /* Get the middle element and make it root */    int mid = (start + end)/2;     node *root = newNode(arr[mid]); Â
    /* Recursively construct the left subtree and make it     left child of root */    root->left = sortedArrayToBST(arr, start, mid-1); Â
    /* Recursively construct the right subtree and make it     right child of root */    root->right = sortedArrayToBST(arr, mid+1, end); Â
    return root; } Â
/* Driver code*/int main() {     /* Create following tree as first balanced BST         100         / \         50 300     / \     20 70     */    node *root1 = newNode(100);     root1->left    = newNode(50);     root1->right = newNode(300);     root1->left->left = newNode(20);     root1->left->right = newNode(70); Â
    /* Create following tree as second balanced BST             80         / \         40 120     */    node *root2 = newNode(80);     root2->left    = newNode(40);     root2->right = newNode(120); Â
    node *mergedTree = mergeTrees(root1, root2, 5, 3); Â
    cout << "Following is Inorder traversal of the merged tree \n";     printInorder(mergedTree); Â
    return 0; } Â
// This code is contributed by rathbhupendra |
C
// C program to Merge Two Balanced Binary Search Trees#include <stdio.h>#include <stdlib.h>Â
/* A binary tree node has data, pointer to left child   and a pointer to right child */struct node{    int data;    struct node* left;    struct node* right;};Â
// A utility function to merge two sorted arrays into oneint *merge(int arr1[], int arr2[], int m, int n);Â
// A helper function that stores inorder traversal of a tree in inorder arrayvoid storeInorder(struct node* node, int inorder[], int *index_ptr);Â
/* A function that constructs Balanced Binary Search Tree from a sorted arraystruct node* sortedArrayToBST(int arr[], int start, int end);Â
/* This function merges two balanced BSTs with roots as root1 and root2.   m and n are the sizes of the trees respectively */struct node* mergeTrees(struct node *root1, struct node *root2, int m, int n){    // Store inorder traversal of first tree in an array arr1[]    int *arr1 = new int[m];    int i = 0;    storeInorder(root1, arr1, &i);Â
    // Store inorder traversal of second tree in another array arr2[]    int *arr2 = new int[n];    int j = 0;    storeInorder(root2, arr2, &j);Â
    // Merge the two sorted array into one    int *mergedArr = merge(arr1, arr2, m, n);Â
    // Construct a tree from the merged array and return root of the tree    return sortedArrayToBST (mergedArr, 0, m+n-1);}Â
/* Helper function that allocates a new node with the   given data and NULL left and right pointers. */struct node* newNode(int data){    struct node* node = (struct node*)                        malloc(sizeof(struct node));    node->data = data;    node->left = NULL;    node->right = NULL;Â
    return(node);}Â
// A utility function to print inorder traversal of a given binary treevoid printInorder(struct node* node){Â Â Â Â if (node == NULL)Â Â Â Â Â Â Â Â return;Â
    /* first recur on left child */    printInorder(node->left);Â
    printf("%d ", node->data);Â
    /* now recur on right child */    printInorder(node->right);}Â
// A utility function to merge two sorted arrays into oneint *merge(int arr1[], int arr2[], int m, int n){    // mergedArr[] is going to contain result    int *mergedArr = new int[m + n];    int i = 0, j = 0, k = 0;Â
    // Traverse through both arrays    while (i < m && j < n)    {        // Pick the smaller element and put it in mergedArr        if (arr1[i] < arr2[j])        {            mergedArr[k] = arr1[i];            i++;        }        else        {            mergedArr[k] = arr2[j];            j++;        }        k++;    }Â
    // If there are more elements in first array    while (i < m)    {        mergedArr[k] = arr1[i];        i++; k++;    }Â
    // If there are more elements in second array    while (j < n)    {        mergedArr[k] = arr2[j];        j++; k++;    }Â
    return mergedArr;}Â
// A helper function that stores inorder traversal of a tree rooted with nodevoid storeInorder(struct node* node, int inorder[], int *index_ptr){Â Â Â Â if (node == NULL)Â Â Â Â Â Â Â Â return;Â
    /* first recur on left child */    storeInorder(node->left, inorder, index_ptr);Â
    inorder[*index_ptr] = node->data;    (*index_ptr)++; // increase index for next entryÂ
    /* now recur on right child */    storeInorder(node->right, inorder, index_ptr);}Â
/* A function that constructs Balanced Binary Search Tree from a sorted arraystruct node* sortedArrayToBST(int arr[], int start, int end){Â Â Â Â /* Base Case */Â Â Â Â if (start > end)Â Â Â Â Â Â return NULL;Â
    /* Get the middle element and make it root */    int mid = (start + end)/2;    struct node *root = newNode(arr[mid]);Â
    /* Recursively construct the left subtree and make it       left child of root */    root->left = sortedArrayToBST(arr, start, mid-1);Â
    /* Recursively construct the right subtree and make it       right child of root */    root->right = sortedArrayToBST(arr, mid+1, end);Â
    return root;}Â
/* Driver program to test above functions*/int main(){    /* Create following tree as first balanced BST           100          / \        50   300       / \      20 70    */    struct node *root1 = newNode(100);    root1->left        = newNode(50);    root1->right       = newNode(300);    root1->left->left  = newNode(20);    root1->left->right = newNode(70);Â
    /* Create following tree as second balanced BST            80           / \         40  120    */    struct node *root2 = newNode(80);    root2->left        = newNode(40);    root2->right       = newNode(120);Â
    struct node *mergedTree = mergeTrees(root1, root2, 5, 3);Â
    printf ("Following is Inorder traversal of the merged tree \n");    printInorder(mergedTree);Â
    getchar();    return 0;} |
Java
// Java program to Merge Two Balanced Binary Search Treesimport java.io.*;import java.util.ArrayList;Â
// A binary tree nodeclass Node {Â Â Â Â Â Â Â Â Â int data;Â Â Â Â Node left, right;Â Â Â Â Â Â Â Â Â Node(int d) {Â Â Â Â Â Â Â Â data = d;Â Â Â Â Â Â Â Â left = right = null;Â Â Â Â }}Â
class BinarySearchTree{Â Â Â Â Â Â Â Â Â // Root of BSTÂ Â Â Â Node root;Â
    // Constructor    BinarySearchTree() {         root = null;     }         // Inorder traversal of the tree    void inorder()    {        inorderUtil(this.root);    }     // Utility function for inorder traversal of the treevoid inorderUtil(Node node){    if(node==null)        return;             inorderUtil(node.left);    System.out.print(node.data + " ");    inorderUtil(node.right);}     Â
    // A Utility Method that stores inorder traversal of a tree    public ArrayList<Integer> storeInorderUtil(Node node, ArrayList<Integer> list)    {        if(node == null)            return list;                 //recur on the left child        storeInorderUtil(node.left, list);                 // Adds data to the list        list.add(node.data);                 //recur on the right child        storeInorderUtil(node.right, list);                 return list;    }         // Method that stores inorder traversal of a tree    ArrayList<Integer> storeInorder(Node node)    {        ArrayList<Integer> list1 = new ArrayList<>();         ArrayList<Integer> list2 = storeInorderUtil(node,list1);         return list2;    }Â
    // Method that merges two ArrayLists into one.     ArrayList<Integer> merge(ArrayList<Integer>list1, ArrayList<Integer>list2, int m, int n)    {        // list3 will contain the merge of list1 and list2        ArrayList<Integer> list3 = new ArrayList<>();        int i=0;        int j=0;                 //Traversing through both ArrayLists        while( i<m && j<n)        {            // Smaller one goes into list3            if(list1.get(i)<list2.get(j))            {                list3.add(list1.get(i));                i++;            }            else            {                list3.add(list2.get(j));                j++;            }        }                 // Adds the remaining elements of list1 into list3        while(i<m)        {            list3.add(list1.get(i));            i++;        }             // Adds the remaining elements of list2 into list3        while(j<n)        {            list3.add(list2.get(j));            j++;        }        return list3;    }         // Method that converts an ArrayList to a BST    Node ALtoBST(ArrayList<Integer>list, int start, int end)    {        // Base case        if(start > end)            return null;             // Get the middle element and make it root            int mid = (start+end)/2;        Node node = new Node(list.get(mid));Â
        /* Recursively construct the left subtree and make it        left child of root */        node.left = ALtoBST(list, start, mid-1);                 /* Recursively construct the right subtree and make it        right child of root */        node.right = ALtoBST(list, mid+1, end);         return node;    }         // Method that merges two trees into a single one.     Node mergeTrees(Node node1, Node node2)    {        //Stores Inorder of tree1 to list1        ArrayList<Integer>list1 = storeInorder(node1);                 //Stores Inorder of tree2 to list2        ArrayList<Integer>list2 = storeInorder(node2);                 // Merges both list1 and list2 into list3        ArrayList<Integer>list3 = merge(list1, list2, list1.size(), list2.size());                 //Eventually converts the merged list into resultant BST        Node node = ALtoBST(list3, 0, list3.size()-1);        return node;    }Â
    // Driver function    public static void main (String[] args)    {                 /* Creating following tree as First balanced BST                100                / \                50 300                / \               20 70        */                 BinarySearchTree tree1 = new BinarySearchTree();        tree1.root = new Node(100);        tree1.root.left = new Node(50);        tree1.root.right = new Node(300);        tree1.root.left.left = new Node(20);        tree1.root.left.right = new Node(70);                 /* Creating following tree as second balanced BST                80                / \              40 120        */                     BinarySearchTree tree2 = new BinarySearchTree();        tree2.root = new Node(80);           tree2.root.left = new Node(40);        tree2.root.right = new Node(120);                                  BinarySearchTree tree = new BinarySearchTree();           tree.root = tree.mergeTrees(tree1.root, tree2.root);        System.out.println("The Inorder traversal of the merged BST is: ");        tree.inorder();    }}// This code has been contributed by Kamal Rawal |
Python3
# A binary tree node has data, pointer to left child # and a pointer to right childclass Node:    def __init__(self, val):        self.val = val        self.left = None        self.right = NoneÂ
# A utility function to merge two sorted arrays into one# Time Complexity of below function: O(m + n)# Space Complexity of below function: O(m + n)def merge_sorted_arr(arr1, arr2):Â Â Â Â arr = []Â Â Â Â i = j = 0Â Â Â Â while i < len(arr1) and j < len(arr2):Â Â Â Â Â Â Â Â if arr1[i] <= arr2[j]:Â Â Â Â Â Â Â Â Â Â Â Â arr.append(arr1[i])Â Â Â Â Â Â Â Â Â Â Â Â i += 1Â Â Â Â Â Â Â Â else:Â Â Â Â Â Â Â Â Â Â Â Â arr.append(arr2[j])Â Â Â Â Â Â Â Â Â Â Â Â j += 1Â Â Â Â while i < len(arr1):Â Â Â Â Â Â Â Â arr.append(arr1[i])Â Â Â Â Â Â Â Â i += 1Â Â Â Â while i < len(arr2):Â Â Â Â Â Â Â Â arr.append(arr2[j])Â Â Â Â Â Â Â Â j += 1Â Â Â Â return arrÂ
# A helper function that stores inorder# traversal of a tree in arrdef inorder(root, arr = []):Â Â Â Â if root:Â Â Â Â Â Â Â Â inorder(root.left, arr)Â Â Â Â Â Â Â Â arr.append(root.val)Â Â Â Â Â Â Â Â inorder(root.right, arr)Â
# A utility function to insert the values# in the individual Treedef insert(root, val):    if not root:        return Node(val)    if root.val == val:        return root    elif root.val > val:        root.left = insert(root.left, val)    else:        root.right = insert(root.right, val)    return rootÂ
# Converts the merged array to a balanced BST# Explanation of the below code:def arr_to_bst(arr):    if not arr:        return None    mid = len(arr) // 2    root = Node(arr[mid])    root.left = arr_to_bst(arr[:mid])    root.right = arr_to_bst(arr[mid + 1:])    return rootÂ
if __name__=='__main__':    root1 = root2 = None         # Inserting values in first tree    root1 = insert(root1, 100)    root1 = insert(root1, 50)    root1 = insert(root1, 300)    root1 = insert(root1, 20)    root1 = insert(root1, 70)         # Inserting values in second tree    root2 = insert(root2, 80)    root2 = insert(root2, 40)    root2 = insert(root2, 120)    arr1 = []    inorder(root1, arr1)    arr2 = []    inorder(root2, arr2)    arr = merge_sorted_arr(arr1, arr2)    root = arr_to_bst(arr)    res = []    inorder(root, res)    print('Following is Inorder traversal of the merged tree')    for i in res:      print(i, end = ' ')       # This code is contributed by Flarow4 |
C#
// C# program to Merge Two Balanced Binary Search Treesusing System;using System.Collections.Generic;Â
// A binary tree node public class Node{Â
    public int data;    public Node left, right;Â
    public Node(int d)    {        data = d;        left = right = null;    }}Â
public class BinarySearchTree{Â
    // Root of BST     public Node root;Â
    // Constructor     public BinarySearchTree()    {        root = null;    }Â
    // Inorder traversal of the tree     public virtual void inorder()    {        inorderUtil(this.root);    }Â
// Utility function for inorder traversal of the tree public virtual void inorderUtil(Node node){Â Â Â Â if (node == null)Â Â Â Â {Â Â Â Â Â Â Â Â return;Â Â Â Â }Â
    inorderUtil(node.left);    Console.Write(node.data + " ");    inorderUtil(node.right);}Â
Â
    // A Utility Method that stores inorder traversal of a tree     public virtual List<int> storeInorderUtil(Node node, List<int> list)    {        if (node == null)        {            return list;        }Â
        //recur on the left child         storeInorderUtil(node.left, list);Â
        // Adds data to the list         list.Add(node.data);Â
        //recur on the right child         storeInorderUtil(node.right, list);Â
        return list;    }Â
    // Method that stores inorder traversal of a tree     public virtual List<int> storeInorder(Node node)    {        List<int> list1 = new List<int>();        List<int> list2 = storeInorderUtil(node,list1);        return list2;    }Â
    // Method that merges two ArrayLists into one.     public virtual List<int> merge(List<int> list1, List<int> list2, int m, int n)    {        // list3 will contain the merge of list1 and list2         List<int> list3 = new List<int>();        int i = 0;        int j = 0;Â
        //Traversing through both ArrayLists         while (i < m && j < n)        {            // Smaller one goes into list3             if (list1[i] < list2[j])            {                list3.Add(list1[i]);                i++;            }            else            {                list3.Add(list2[j]);                j++;            }        }Â
        // Adds the remaining elements of list1 into list3         while (i < m)        {            list3.Add(list1[i]);            i++;        }Â
        // Adds the remaining elements of list2 into list3         while (j < n)        {            list3.Add(list2[j]);            j++;        }        return list3;    }Â
    // Method that converts an ArrayList to a BST     public virtual Node ALtoBST(List<int> list, int start, int end)    {        // Base case         if (start > end)        {            return null;        }Â
        // Get the middle element and make it root             int mid = (start + end) / 2;        Node node = new Node(list[mid]);Â
        /* Recursively construct the left subtree and make it         left child of root */        node.left = ALtoBST(list, start, mid - 1);Â
        /* Recursively construct the right subtree and make it         right child of root */        node.right = ALtoBST(list, mid + 1, end);Â
    return node;    }Â
    // Method that merges two trees into a single one.     public virtual Node mergeTrees(Node node1, Node node2)    {        //Stores Inorder of tree1 to list1         List<int> list1 = storeInorder(node1);Â
        //Stores Inorder of tree2 to list2         List<int> list2 = storeInorder(node2);Â
        // Merges both list1 and list2 into list3         List<int> list3 = merge(list1, list2, list1.Count, list2.Count);Â
        //Eventually converts the merged list into resultant BST         Node node = ALtoBST(list3, 0, list3.Count - 1);        return node;    }Â
    // Driver function     public static void Main(string[] args)    {Â
        /* Creating following tree as First balanced BST                 100                 / \                 50 300                 / \                20 70         */Â
        BinarySearchTree tree1 = new BinarySearchTree();        tree1.root = new Node(100);        tree1.root.left = new Node(50);        tree1.root.right = new Node(300);        tree1.root.left.left = new Node(20);        tree1.root.left.right = new Node(70);Â
        /* Creating following tree as second balanced BST                 80                 / \               40 120         */Â
        BinarySearchTree tree2 = new BinarySearchTree();        tree2.root = new Node(80);        tree2.root.left = new Node(40);        tree2.root.right = new Node(120);Â
Â
        BinarySearchTree tree = new BinarySearchTree();        tree.root = tree.mergeTrees(tree1.root, tree2.root);        Console.WriteLine("The Inorder traversal of the merged BST is: ");        tree.inorder();    }}Â
  // This code is contributed by Shrikant13 |
Javascript
<script>Â
      // JavaScript program to Merge Two       // Balanced Binary Search Trees      // A binary tree node      class Node {        constructor(d) {          this.data = d;          this.left = null;          this.right = null;        }      }Â
      class BinarySearchTree {        // Constructor        constructor() {          this.root = null;        }Â
        // Inorder traversal of the tree        inorder() {          this.inorderUtil(this.root);        }Â
        // Utility function for inorder traversal of the tree        inorderUtil(node) {          if (node == null) {            return;          }Â
          this.inorderUtil(node.left);          document.write(node.data + " ");          this.inorderUtil(node.right);        }Â
        // A Utility Method that stores         // inorder traversal of a tree        storeInorderUtil(node, list) {          if (node == null) {            return list;          }Â
          //recur on the left child          this.storeInorderUtil(node.left, list);Â
          // Adds data to the list          list.push(node.data);Â
          //recur on the right child          this.storeInorderUtil(node.right, list);Â
          return list;        }Â
        // Method that stores inorder traversal of a tree        storeInorder(node) {          var list1 = [];          var list2 = this.storeInorderUtil(node, list1);          return list2;        }Â
        // Method that merges two ArrayLists into one.        merge(list1, list2, m, n) {          // list3 will contain the merge of list1 and list2          var list3 = [];          var i = 0;          var j = 0;Â
          //Traversing through both ArrayLists          while (i < m && j < n) {            // Smaller one goes into list3            if (list1[i] < list2[j]) {              list3.push(list1[i]);              i++;            } else {              list3.push(list2[j]);              j++;            }          }Â
          // Adds the remaining elements of list1 into list3          while (i < m) {            list3.push(list1[i]);            i++;          }Â
          // Adds the remaining elements of list2 into list3          while (j < n) {            list3.push(list2[j]);            j++;          }          return list3;        }Â
        // Method that converts an ArrayList to a BST        ALtoBST(list, start, end) {          // Base case          if (start > end) {            return null;          }Â
          // Get the middle element and make it root          var mid = parseInt((start + end) / 2);          var node = new Node(list[mid]);Â
          /* Recursively construct the left subtree and make it        left child of root */          node.left = this.ALtoBST(list, start, mid - 1);Â
          /* Recursively construct the right subtree and make it        right child of root */          node.right = this.ALtoBST(list, mid + 1, end);Â
          return node;        }Â
        // Method that merges two trees into a single one.        mergeTrees(node1, node2) {          //Stores Inorder of tree1 to list1          var list1 = this.storeInorder(node1);Â
          //Stores Inorder of tree2 to list2          var list2 = this.storeInorder(node2);Â
          // Merges both list1 and list2 into list3          var list3 =           this.merge(list1, list2, list1.length, list2.length);Â
          //Eventually converts the merged list into resultant BST          var node = this.ALtoBST(list3, 0, list3.length - 1);          return node;        }      }      // Driver function      /* Creating following tree as First balanced BST                100                / \                50 300                / \            20 70        */Â
      var tree1 = new BinarySearchTree();      tree1.root = new Node(100);      tree1.root.left = new Node(50);      tree1.root.right = new Node(300);      tree1.root.left.left = new Node(20);      tree1.root.left.right = new Node(70);Â
      /* Creating following tree as second balanced BST                80                / \            40 120        */Â
      var tree2 = new BinarySearchTree();      tree2.root = new Node(80);      tree2.root.left = new Node(40);      tree2.root.right = new Node(120);Â
      var tree = new BinarySearchTree();      tree.root = tree.mergeTrees(tree1.root, tree2.root);      document.write(      "Following is Inorder traversal of the merged tree <br>"      );      tree.inorder();       </script> |
Following is Inorder traversal of the merged tree 20 40 50 70 80 100 120 300
 Time complexity: O(m+n), where m and n are the numbers of elements in the two binary search trees.
 Space complexity: O(m+n). This is because we need to allocate space for the two arrays that store the elements from the two binary search trees, as well as an array to store the merged elements.
Method 3 (In-Place Merge using DLL):
We can use a Doubly Linked List to merge trees in place. Following are the steps.
- Convert the given two Binary Search Trees into a doubly linked list in place (Refer to this post for this step).Â
- Merge the two sorted Linked Lists (Refer to this post for this step).Â
- Build a Balanced Binary Search Tree from the merged list created in step 2. (Refer to this post for this step)
The time complexity of this method is also O(m+n) and this method does conversion in place.
Thanks to Dheeraj and Ronzii for suggesting this method.
C++
// C++ Code for the above approachÂ
#include <bits/stdc++.h>using namespace std;Â
/* A binary tree node has data,a pointer to left childand a pointer to right child */class Node {public:Â Â Â Â int data;Â Â Â Â Node* left;Â Â Â Â Node* right;};Â
// Function to return a new NodeNode* newNode(int data){Â Â Â Â Node* node = new Node();Â Â Â Â node->data = data;Â Â Â Â node->left = NULL;Â Â Â Â node->right = NULL;Â
    return (node);}Â
// Function to convert bst to// a doubly linked listvoid bstTodll(Node* root, Node*& head){Â Â Â Â // if root is NULLÂ Â Â Â if (!root)Â Â Â Â Â Â Â Â return;Â
    // Convert right subtree recursively    bstTodll(root->right, head);Â
    // Update root    root->right = head;Â
    // if head is not NULL    if (head) {Â
        // Update left of the head        head->left = root;    }Â
    // Update head    head = root;Â
    // Convert left subtree recursively    bstTodll(root->left, head);}Â
// Function to merge two sorted linked listNode* mergeLinkedList(Node* head1, Node* head2){Â
    /*Create head and tail for result list*/    Node* head = NULL;    Node* tail = NULL;Â
    while (head1 && head2) {Â
        if (head1->data < head2->data) {Â
            if (!head)                head = head1;            else {Â
                tail->right = head1;                head1->left = tail;            }Â
            tail = head1;            head1 = head1->right;        }Â
        else {Â
            if (!head)                head = head2;            else {                tail->right = head2;                head2->left = tail;            }Â
            tail = head2;            head2 = head2->right;        }    }Â
    while (head1) {        tail->right = head1;        head1->left = tail;        tail = head1;        head1 = head1->right;    }Â
    while (head2) {        tail->right = head2;        head2->left = tail;        tail = head2;        head2 = head2->right;    }Â
    // Return the created DLL    return head;}Â
// function to convert list to bstNode* sortedListToBST(Node*& head, int n){    // if no element is left or head is null    if (n <= 0 || !head)        return NULL;Â
    // Create left part from the list recursively    Node* left = sortedListToBST(head, n / 2);Â
    Node* root = head;    root->left = left;    head = head->right;Â
    // Create left part from the list recursively    root->right = sortedListToBST(head, n - (n / 2) - 1);Â
    // Return the root of BST    return root;}Â
// This function merges two balanced BSTsNode* mergeTrees(Node* root1, Node* root2, int m, int n){Â Â Â Â // Convert BSTs into sorted Doubly Linked ListsÂ
    Node* head1 = NULL;    bstTodll(root1, head1);    head1->left = NULL;Â
    Node* head2 = NULL;    bstTodll(root2, head2);    head2->left = NULL;Â
    // Merge the two sorted lists into one    Node* head = mergeLinkedList(head1, head2);Â
    // Construct a tree from the merged lists    return sortedListToBST(head, m + n);}Â
void printInorder(Node* node){Â Â Â Â // if current node is NULLÂ Â Â Â if (!node) {Â Â Â Â Â Â Â Â return;Â Â Â Â }Â
    printInorder(node->left);Â
      // Print node of current data    cout << node->data << " ";Â
    printInorder(node->right);}Â
/* Driver code*/int main(){Â Â Â Â /* Create following tree as first balanced BSTÂ Â Â Â Â Â Â 100Â Â Â Â Â Â Â / \Â Â Â Â Â Â 50 300Â Â Â Â Â / \Â Â Â Â 20 70Â Â */Â
    Node* root1 = newNode(100);    root1->left = newNode(50);    root1->right = newNode(300);    root1->left->left = newNode(20);    root1->left->right = newNode(70);Â
    /* Create following tree as second balanced BST             80            / \           40 120    */    Node* root2 = newNode(80);    root2->left = newNode(40);    root2->right = newNode(120);Â
      // Function Call    Node* mergedTree = mergeTrees(root1, root2, 5, 3);Â
    cout << "Following is Inorder traversal of the merged "            "tree \n";    printInorder(mergedTree);Â
    return 0;}Â
// This code is contributed by Tapesh(tapeshdua420) |
Java
// Java Code for the above approachimport java.util.*;Â
/* A binary tree node has data,a pointer to left childand a pointer to right child */class Node {Â Â Â Â int data;Â Â Â Â Node left, right;Â
    Node(int d)    {        data = d;        left = right = null;    }}Â
// Function to return a new Nodepublic class Main {Â
    Node newNode(int data)    {        Node node = new Node(data);        node.left = null;        node.right = null;        return (node);    }Â
    // Function to convert bst to a doubly linked list    void bstTodll(Node root, Node[] head)    {Â
        // if root is NULL        if (root == null)            return;Â
        // Convert right subtree recursively        bstTodll(root.right, head);Â
        // Update root        root.right = head[0];Â
        // if head is not NULL        if (head[0] != null) {Â
            // Update left of the head            head[0].left = root;        }Â
        // Update head        head[0] = root;Â
        // Convert left subtree recursively        bstTodll(root.left, head);    }Â
    // Function to merge two sorted linked list    Node mergeLinkedList(Node head1, Node head2)    {Â
        /*Create head and tail for result list*/        Node head = null, tail = null;        while (head1 != null && head2 != null) {            if (head1.data < head2.data) {                if (head == null) {                    head = head1;                }                else {                    tail.right = head1;                    head1.left = tail;                }                tail = head1;                head1 = head1.right;            }            else {                if (head == null) {                    head = head2;                }                else {                    tail.right = head2;                    head2.left = tail;                }                tail = head2;                head2 = head2.right;            }        }        while (head1 != null) {            tail.right = head1;            head1.left = tail;            tail = head1;            head1 = head1.right;        }        while (head2 != null) {            tail.right = head2;            head2.left = tail;            tail = head2;            head2 = head2.right;        }Â
        // Return the created DLL        return head;    }Â
    // function to convert list to bst    Node sortedListToBST(Node[] head, int n)    {Â
        // if no element is left or head is null        if (n <= 0 || head[0] == null)            return null;Â
        // Create left part from the list recursively        Node left = sortedListToBST(head, n / 2);        Node root = head[0];        root.left = left;        head[0] = head[0].right;Â
        // Create left part from the list recursively        root.right = sortedListToBST(head, n - (n / 2) - 1);Â
        // Return the root of BST        return root;    }Â
    // This function merges two balanced BSTs    Node mergeTrees(Node root1, Node root2, int m, int n)    {Â
        // Convert BSTs into sorted Doubly Linked ListsÂ
        Node[] head1 = new Node[1];        head1[0] = null;        bstTodll(root1, head1);        head1[0].left = null;Â
        Node[] head2 = new Node[1];        head2[0] = null;        bstTodll(root2, head2);        head2[0].left = null;Â
        // Merge the two sorted lists into one        Node head = mergeLinkedList(head1[0], head2[0]);Â
        // Construct a tree from the merged lists        return sortedListToBST(new Node[] { head }, m + n);    }Â
    void printInorder(Node node)    {Â
        // if current node is NULL        if (node == null) {            return;        }        printInorder(node.left);Â
        // Print node of current data        System.out.print(node.data + " ");Â
        printInorder(node.right);    }Â
    /* Driver code*/    public static void main(String[] args)    {        Main obj = new Main();Â
        /* Create following tree as first balanced BST           100           / \          50 300         / \        20 70  */Â
        Node root1 = obj.newNode(100);        root1.left = obj.newNode(50);        root1.right = obj.newNode(300);        root1.left.left = obj.newNode(20);        root1.left.right = obj.newNode(70);Â
        /* Create following tree as second balanced BST                80               / \              40 120       */Â
        Node root2 = obj.newNode(80);        root2.left = obj.newNode(40);        root2.right = obj.newNode(120);Â
        // Function Call        Node mergedTree            = obj.mergeTrees(root1, root2, 5, 3);Â
        System.out.println(            "Following is Inorder traversal of the merged tree:");        obj.printInorder(mergedTree);    }} |
Python
class TreeNode:    def __init__(self, data):        self.data = data        self.left = None        self.right = NoneÂ
class Solution:Â Â Â Â def __init__(self):Â Â Â Â Â Â Â Â self.head1 = [None]Â Â Â Â Â Â Â Â self.head2 = [None]Â
    def newNode(self, data):        node = TreeNode(data)        node.left = None        node.right = None        return nodeÂ
    def bstToDLL(self, root, head):        if not root:            returnÂ
        self.bstToDLL(root.right, head)Â
        root.right = head[0]Â
        if head[0]:            head[0].left = rootÂ
        head[0] = rootÂ
        self.bstToDLL(root.left, head)Â
    def mergeLinkedList(self, head1, head2):        head = None        tail = NoneÂ
        while head1 and head2:            if head1.data < head2.data:                if not head:                    head = head1                else:                    tail.right = head1                    head1.left = tail                tail = head1                head1 = head1.right            else:                if not head:                    head = head2                else:                    tail.right = head2                    head2.left = tail                tail = head2                head2 = head2.rightÂ
        while head1:            tail.right = head1            head1.left = tail            tail = head1            head1 = head1.rightÂ
        while head2:            tail.right = head2            head2.left = tail            tail = head2            head2 = head2.rightÂ
        return headÂ
    def sortedListToBST(self, head, n):        if n <= 0 or not head[0]:            return NoneÂ
        left = self.sortedListToBST(head, n // 2)        root = head[0]        root.left = left        head[0] = head[0].rightÂ
        root.right = self.sortedListToBST(head, n - (n // 2) - 1)Â
        return rootÂ
    def mergeTrees(self, root1, root2, m, n):        self.bstToDLL(root1, self.head1)        self.head1[0].left = NoneÂ
        self.bstToDLL(root2, self.head2)        self.head2[0].left = NoneÂ
        merged_head = self.mergeLinkedList(self.head1[0], self.head2[0])Â
        merged_root = self.sortedListToBST([merged_head], m + n)Â
        return merged_rootÂ
    def printInorder(self, node):        if not node:            return        self.printInorder(node.left)        print(node.data),        self.printInorder(node.right)Â
# Create the first balanced BSTroot1 = TreeNode(100)root1.left = TreeNode(50)root1.right = TreeNode(300)root1.left.left = TreeNode(20)root1.left.right = TreeNode(70)Â
# Create the second balanced BSTroot2 = TreeNode(80)root2.left = TreeNode(40)root2.right = TreeNode(120)Â
solution = Solution()mergedTree = solution.mergeTrees(root1, root2, 5, 3)Â
print("Inorder traversal of the merged tree:")solution.printInorder(mergedTree) |
C#
// C# Code for the above approachusing System;Â
/* A binary tree node has data,a pointer to left childand a pointer to right child */public class Node {Â Â public int data;Â Â public Node left;Â Â public Node right;}Â
public class Program {  // Function to return a new Node  static Node newNode(int data)  {    Node node = new Node();    node.data = data;    node.left = null;    node.right = null;Â
    return node;  }Â
  // Function to convert bst to  // a doubly linked list  static void bstTodll(Node root, ref Node head)  {    // if root is NUL    if (root == null)      return;Â
    // Convert right subtree recursively    bstTodll(root.right, ref head);Â
    // Update root    root.right = head;Â
    // if head is not NULL    if (head != null)Â
      // Update left of the head      head.left = root;Â
    // Update head    head = root;Â
    // Convert left subtree recursively    bstTodll(root.left, ref head);  }Â
  // Function to merge two sorted linked list  static Node mergeLinkedList(Node head1, Node head2)  {    /*Create head and tail for result list*/    Node head = null, tail = null;Â
    while (head1 != null && head2 != null) {      if (head1.data < head2.data) {        if (head == null)          head = head1;        else {          tail.right = head1;          head1.left = tail;        }Â
        tail = head1;        head1 = head1.right;      }      else {        if (head == null)          head = head2;        else {          tail.right = head2;          head2.left = tail;        }Â
        tail = head2;        head2 = head2.right;      }    }Â
    while (head1 != null) {      tail.right = head1;      head1.left = tail;      tail = head1;      head1 = head1.right;    }Â
    while (head2 != null) {      tail.right = head2;      head2.left = tail;      tail = head2;      head2 = head2.right;    }Â
    // Return the created DLL    return head;  }Â
  // function to convert list to bst  static Node sortedListToBST(ref Node head, int n)  {    // if no element is left or head is null    if (n <= 0 || head == null)      return null;    // Create left part from the list recursively    Node left = sortedListToBST(ref head, n / 2);Â
    Node root = head;    root.left = left;    head = head.right;Â
    // Create left part from the list recursively    root.right      = sortedListToBST(ref head, n - (n / 2) - 1);Â
    // Return the root of BST    return root;  }Â
  // This function merges two balanced BSTsÂ
  static Node mergeTrees(Node root1, Node root2, int m,                         int n)  {    // Convert BSTs into sorted Doubly Linked Lists    Node head1 = null;    bstTodll(root1, ref head1);    head1.left = null;Â
    Node head2 = null;    bstTodll(root2, ref head2);    head2.left = null;Â
    // Merge the two sorted lists into one    Node head = mergeLinkedList(head1, head2);Â
    // Construct a tree from the merged lists    return sortedListToBST(ref head, m + n);  }Â
  static void printInorder(Node node)  {    // if current node is NULL    if (node == null)      return;Â
    printInorder(node.left);Â
    // Print node of current data    Console.Write(node.data + " ");    printInorder(node.right);  }Â
  /* Driver code*/  public static void Main()  {Â
    /* Create following tree as first balanced BST           100           / \          50 300         / \        20 70  */    Node root1 = newNode(100);    root1.left = newNode(50);    root1.right = newNode(300);    root1.left.left = newNode(20);    root1.left.right = newNode(70);Â
    /* Create following tree as second balanced BST                 80                / \               40 120        */    Node root2 = newNode(80);    root2.left = newNode(40);    root2.right = newNode(120);Â
    // Function Call    Node mergedTree = mergeTrees(root1, root2, 5, 3);Â
    Console.WriteLine(      "Following is Inorder traversal of the merged tree: ");    printInorder(mergedTree);  }  // This code is contributed by rutikbhosale} |
Javascript
// JavaScrpit Code for above approachÂ
// A binary tree node has data,// a pointer to left child,// and a pointer to right childclass Node {Â Â Â Â constructor(data) {Â Â Â Â Â Â Â Â this.data = data;Â Â Â Â Â Â Â Â this.left = null;Â Â Â Â Â Â Â Â this.right = null;Â Â Â Â }}Â
// Function to convert BST to a doubly linked listfunction bstToDll(root, headRef) {Â Â Â Â if (!root) {Â Â Â Â Â Â Â Â return;Â Â Â Â }Â
    // Convert right subtree recursively    bstToDll(root.right, headRef);Â
    // Update root    root.right = headRef.node;Â
    // Update left of the head if head is not null    if (headRef.node) {        headRef.node.left = root;    }Â
    // Update head    headRef.node = root;Â
    // Convert left subtree recursively    bstToDll(root.left, headRef);}Â
// Function to merge two sorted linked listsfunction mergeLinkedList(head1, head2) {Â Â Â Â let head = null;Â Â Â Â let tail = null;Â
    while (head1 && head2) {        if (head1.data < head2.data) {            if (!head) {                head = head1;            } else {                tail.right = head1;                head1.left = tail;            }            tail = head1;            head1 = head1.right;        } else {            if (!head) {                head = head2;            } else {                tail.right = head2;                head2.left = tail;            }            tail = head2;            head2 = head2.right;        }    }Â
    while (head1) {        tail.right = head1;        head1.left = tail;        tail = head1;        head1 = head1.right;    }Â
    while (head2) {        tail.right = head2;        head2.left = tail;        tail = head2;        head2 = head2.right;    }Â
    // Return the created DLL    return head;}Â
// Function to convert a sorted linked list to a BSTfunction sortedListToBST(headRef, n) {Â Â Â Â if (n <= 0 || !headRef.node) {Â Â Â Â Â Â Â Â return null;Â Â Â Â }Â
    // Create the left part from the list recursively    const left = sortedListToBST(headRef, Math.floor(n / 2));Â
    const root = headRef.node;    root.left = left;    headRef.node = headRef.node.right;Â
    // Create the right part from the list recursively    root.right = sortedListToBST(headRef, n - Math.floor(n / 2) - 1);Â
    // Return the root of the BST    return root;}Â
// This function merges two balanced BSTsfunction mergeTrees(root1, root2, m, n) {    // Convert BSTs into sorted Doubly Linked Lists    const headRef1 = { node: null };    bstToDll(root1, headRef1);    headRef1.node.left = null;Â
    const headRef2 = { node: null };    bstToDll(root2, headRef2);    headRef2.node.left = null;Â
    // Merge the two sorted lists into one    const mergedHead = mergeLinkedList(headRef1.node, headRef2.node);Â
    // Construct a tree from the merged lists    return sortedListToBST({ node: mergedHead }, m + n);}Â
function printInorder(node) {Â Â Â Â if (!node) {Â Â Â Â Â Â Â Â return;Â Â Â Â }Â
    printInorder(node.left);    console.log(node.data);    printInorder(node.right);}Â
// Driver code// Create the first balanced BSTconst root1 = new Node(100);root1.left = new Node(50);root1.right = new Node(300);root1.left.left = new Node(20);root1.left.right = new Node(70);Â
// Create the second balanced BSTconst root2 = new Node(80);root2.left = new Node(40);root2.right = new Node(120);Â
// Function call to merge the treesconst mergedTree = mergeTrees(root1, root2, 5, 3);Â
console.log("Following is Inorder traversal of the merged tree:");printInorder(mergedTree); |
Following is Inorder traversal of the merged tree 20 40 50 70 80 100 120 300
Time Complexity: O(N + M). where N and M are the numbers of nodes in the given trees.
Auxiliary Space: O(1), as constant extra space is used.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
