Related Articles
Print Common Nodes in Two Binary Search Trees
• Difficulty Level : Hard
• Last Updated : 28 Aug, 2020

Given two Binary Search Trees, find common nodes in them. In other words, find intersection of two BSTs.

## Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

Method 1 (Simple Solution) A simple way is to one by once search every node of first tree in second tree. Time complexity of this solution is O(m * h) where m is number of nodes in first tree and h is height of second tree.

Method 2:

• Approach – If we think of another problem in which we are given two sorted arrays and we have to find the intersection between them, we can do it easily using two pointer technique. Now we can easily convert this problem into above. We know that if we store the inorder traversal of a BST in an array, that array will be sorted in ascending order. So what we can do is simply take the inorder traversal of both the trees and store them in two seperate arrays and then find intersection between two arrays.
• Algorithm –
1) Do inorder traversal of first tree and store the traversal in an auxiliary array ar1[]. See sortedInorder() here.
2) Do inorder traversal of second tree and store the traversal in an auxiliary array ar2[]
3) Find intersection of ar1[] and ar2[]. See this for details.
• Complexity Analysis:
• Time Complexity: O(m+n).
Here ‘m’ and ‘n’ are number of nodes in first and second tree respectively,as we need to traverse both the trees.
• Auxiliary Space :No use of any data structure for storing values-: O(m+n)
The reason is that we need two seperate arrays for storing inorder traversals of both the trees.

Method 3 (Linear Time and limited Extra Space)
The idea is to use iterative inorder traversal

• Approach:
The idea here is to optimise the space. In the above approach we store all the elements of the tree and then compare but the question is it really necessary to store all the elements. What one can do is store a particular branch of the tree (worst case ‘Height of the tree’) and then start comparing. We can take two stacks and store inorder traversal of trees in respective stacks but the maximum number of elements should be equal to that particular branch of the tree. As soon as that branch ends we start popping and comparing the elements of the stack. Now if top(stack-1)<top(stack-2) there can be more elements in the right branch of top(stack-1) which are greater than it and can be equal to top(stack-2). So we insert right branch of top(stack-1) till it is equal to NULL. At the end of each such insertion we have three conditions to check and then we do the insertions in the stack accordingly.
```if top(stack-1)<top(stack-2)
root1=root1->right (then do insertions)

if top(stack-1)>top(stack-2)
root2=root2->right (then do insertions)

else
It's a match
```

## C++

 `// C++ program of iterative traversal based method to``// find common elements in two BSTs.``#include``#include``using` `namespace` `std;`` ` `// A BST node``struct` `Node``{``    ``int` `key;``    ``struct` `Node *left, *right;``};`` ` `// A utility function to create a new node``Node *newNode(``int` `ele)``{``    ``Node *temp = ``new` `Node;``    ``temp->key = ele;``    ``temp->left = temp->right = NULL;``    ``return` `temp;``}`` ` `// Function two print common elements in given two trees``void` `printCommon(Node *root1, Node *root2)``{``    ``// Create two stacks for two inorder traversals``    ``stack stack1, s1, s2;`` ` `    ``while` `(1)``    ``{``        ``// push the Nodes of first tree in stack s1``        ``if` `(root1)``        ``{``            ``s1.push(root1);``            ``root1 = root1->left;``        ``}`` ` `        ``// push the Nodes of second tree in stack s2``        ``else` `if` `(root2)``        ``{``            ``s2.push(root2);``            ``root2 = root2->left;``        ``}`` ` `        ``// Both root1 and root2 are NULL here``        ``else` `if` `(!s1.empty() && !s2.empty())``        ``{``            ``root1 = s1.top();``            ``root2 = s2.top();`` ` `            ``// If current keys in two trees are same``            ``if` `(root1->key == root2->key)``            ``{``                ``cout << root1->key << ``" "``;``                ``s1.pop();``                ``s2.pop();`` ` `                ``// move to the inorder successor``                ``root1 = root1->right;``                ``root2 = root2->right;``            ``}`` ` `            ``else` `if` `(root1->key < root2->key)``            ``{``                ``// If Node of first tree is smaller, than that of``                ``// second tree, then its obvious that the inorder``                ``// successors of current Node can have same value``                ``// as that of the second tree Node. Thus, we pop``                ``// from s2``                ``s1.pop();``                ``root1 = root1->right;`` ` `                ``// root2 is set to NULL, because we need``                ``// new Nodes of tree 1``                ``root2 = NULL;``            ``}``            ``else` `if` `(root1->key > root2->key)``            ``{``                ``s2.pop();``                ``root2 = root2->right;``                ``root1 = NULL;``            ``}``        ``}`` ` `        ``// Both roots and both stacks are empty``        ``else`  `break``;``    ``}``}`` ` `// A utility function to do inorder traversal``void` `inorder(``struct` `Node *root)``{``    ``if` `(root)``    ``{``        ``inorder(root->left);``        ``cout<key<<``" "``;``        ``inorder(root->right);``    ``}``}`` ` `/* A utility function to insert a new Node with given key in BST */``struct` `Node* insert(``struct` `Node* node, ``int` `key)``{``    ``/* If the tree is empty, return a new Node */``    ``if` `(node == NULL) ``return` `newNode(key);`` ` `    ``/* Otherwise, recur down the tree */``    ``if` `(key < node->key)``        ``node->left  = insert(node->left, key);``    ``else` `if` `(key > node->key)``        ``node->right = insert(node->right, key);`` ` `    ``/* return the (unchanged) Node pointer */``    ``return` `node;``}`` ` `// Driver program``int` `main()``{``    ``// Create first tree as shown in example``    ``Node *root1 = NULL;``    ``root1 = insert(root1, 5);``    ``root1 = insert(root1, 1);``    ``root1 = insert(root1, 10);``    ``root1 = insert(root1,  0);``    ``root1 = insert(root1,  4);``    ``root1 = insert(root1,  7);``    ``root1 = insert(root1,  9);`` ` `    ``// Create second tree as shown in example``    ``Node *root2 = NULL;``    ``root2 = insert(root2, 10);``    ``root2 = insert(root2, 7);``    ``root2 = insert(root2, 20);``    ``root2 = insert(root2, 4);``    ``root2 = insert(root2, 9);`` ` `    ``cout << ``"Tree 1 : "``;``    ``inorder(root1);``    ``cout << endl;`` ` `    ``cout << ``"Tree 2 : "``;``    ``inorder(root2);`` ` `    ``cout << ``"\nCommon Nodes: "``;``    ``printCommon(root1, root2);`` ` `    ``return` `0;``}`

## Java

 `// Java program of iterative traversal based method to ``// find common elements in two BSTs.``import` `java.util.*;``class` `GfG { `` ` `// A BST node ``static` `class` `Node ``{ ``    ``int` `key; ``    ``Node left, right; ``}`` ` `// A utility function to create a new node ``static` `Node newNode(``int` `ele) ``{ ``    ``Node temp = ``new` `Node(); ``    ``temp.key = ele; ``    ``temp.left = ``null``;``    ``temp.right = ``null``; ``    ``return` `temp; ``} `` ` `// Function two print common elements in given two trees ``static` `void` `printCommon(Node root1, Node root2) ``{ ``     ` `    ``Stack s1 = ``new` `Stack (); ``    ``Stack s2 = ``new` `Stack ();`` ` `    ``while` `(``true``) ``    ``{ ``        ``// push the Nodes of first tree in stack s1 ``        ``if` `(root1 != ``null``) ``        ``{ ``            ``s1.push(root1); ``            ``root1 = root1.left; ``        ``} `` ` `        ``// push the Nodes of second tree in stack s2 ``        ``else` `if` `(root2 != ``null``) ``        ``{ ``            ``s2.push(root2); ``            ``root2 = root2.left; ``        ``} `` ` `        ``// Both root1 and root2 are NULL here ``        ``else` `if` `(!s1.isEmpty() && !s2.isEmpty()) ``        ``{ ``            ``root1 = s1.peek(); ``            ``root2 = s2.peek(); `` ` `            ``// If current keys in two trees are same ``            ``if` `(root1.key == root2.key) ``            ``{ ``                ``System.out.print(root1.key + ``" "``); ``                ``s1.pop(); ``                ``s2.pop(); `` ` `                ``// move to the inorder successor ``                ``root1 = root1.right; ``                ``root2 = root2.right; ``            ``} `` ` `            ``else` `if` `(root1.key < root2.key) ``            ``{ ``                ``// If Node of first tree is smaller, than that of ``                ``// second tree, then its obvious that the inorder ``                ``// successors of current Node can have same value ``                ``// as that of the second tree Node. Thus, we pop ``                ``// from s2 ``                ``s1.pop(); ``                ``root1 = root1.right; `` ` `                ``// root2 is set to NULL, because we need ``                ``// new Nodes of tree 1 ``                ``root2 = ``null``; ``            ``} ``            ``else` `if` `(root1.key > root2.key) ``            ``{ ``                ``s2.pop(); ``                ``root2 = root2.right; ``                ``root1 = ``null``; ``            ``} ``        ``} `` ` `        ``// Both roots and both stacks are empty ``        ``else` `break``; ``    ``} ``} `` ` `// A utility function to do inorder traversal ``static` `void` `inorder(Node root) ``{ ``    ``if` `(root != ``null``) ``    ``{ ``        ``inorder(root.left); ``        ``System.out.print(root.key + ``" "``); ``        ``inorder(root.right); ``    ``} ``} `` ` `/* A utility function to insert a new Node with given key in BST */``static` `Node insert(Node node, ``int` `key) ``{ ``    ``/* If the tree is empty, return a new Node */``    ``if` `(node == ``null``) ``return` `newNode(key); `` ` `    ``/* Otherwise, recur down the tree */``    ``if` `(key < node.key) ``        ``node.left = insert(node.left, key); ``    ``else` `if` `(key > node.key) ``        ``node.right = insert(node.right, key); `` ` `    ``/* return the (unchanged) Node pointer */``    ``return` `node; ``} `` ` `// Driver program ``public` `static` `void` `main(String[] args) ``{ ``    ``// Create first tree as shown in example ``    ``Node root1 = ``null``; ``    ``root1 = insert(root1, ``5``); ``    ``root1 = insert(root1, ``1``); ``    ``root1 = insert(root1, ``10``); ``    ``root1 = insert(root1, ``0``); ``    ``root1 = insert(root1, ``4``); ``    ``root1 = insert(root1, ``7``); ``    ``root1 = insert(root1, ``9``); `` ` `    ``// Create second tree as shown in example ``    ``Node root2 = ``null``; ``    ``root2 = insert(root2, ``10``); ``    ``root2 = insert(root2, ``7``); ``    ``root2 = insert(root2, ``20``); ``    ``root2 = insert(root2, ``4``); ``    ``root2 = insert(root2, ``9``); `` ` `    ``System.out.print(``"Tree 1 : "` `+ ``"\n"``); ``    ``inorder(root1); ``    ``System.out.println();``    ``System.out.print(``"Tree 2 : "` `+ ``"\n"``); ``    ``inorder(root2); ``    ``System.out.println();``    ``System.out.println(``"Common Nodes: "``);`` ` `    ``printCommon(root1, root2); `` ` `}``} `

## Python3

 `# Python3 program of iterative traversal based ``# method to find common elements in two BSTs. `` ` `# A utility function to create a new node ``class` `newNode:``    ``def` `__init__(``self``, key):``        ``self``.key ``=` `key``        ``self``.left ``=` `self``.right ``=` `None`` ` `# Function two print common elements ``# in given two trees ``def` `printCommon(root1, root2):``     ` `    ``# Create two stacks for two inorder``    ``# traversals ``    ``s1 ``=` `[]``    ``s2 ``=` `[]`` ` `    ``while` `1``:``         ` `        ``# append the Nodes of first ``        ``# tree in stack s1 ``        ``if` `root1:``            ``s1.append(root1)``            ``root1 ``=` `root1.left`` ` `        ``# append the Nodes of second tree``        ``# in stack s2 ``        ``elif` `root2:``            ``s2.append(root2)``            ``root2 ``=` `root2.left`` ` `        ``# Both root1 and root2 are NULL here ``        ``elif` `len``(s1) !``=` `0` `and` `len``(s2) !``=` `0``:``            ``root1 ``=` `s1[``-``1``] ``            ``root2 ``=` `s2[``-``1``] `` ` `            ``# If current keys in two trees are same ``            ``if` `root1.key ``=``=` `root2.key:``                ``print``(root1.key, end ``=` `" "``)``                ``s1.pop(``-``1``) ``                ``s2.pop(``-``1``)`` ` `                ``# move to the inorder successor ``                ``root1 ``=` `root1.right ``                ``root2 ``=` `root2.right`` ` `            ``elif` `root1.key < root2.key:``                 ` `                ``# If Node of first tree is smaller, than ``                ``# that of second tree, then its obvious ``                ``# that the inorder successors of current ``                ``# Node can have same value as that of the ``                ``# second tree Node. Thus, we pop from s2 ``                ``s1.pop(``-``1``)``                ``root1 ``=` `root1.right `` ` `                ``# root2 is set to NULL, because we need ``                ``# new Nodes of tree 1 ``                ``root2 ``=` `None``            ``elif` `root1.key > root2.key:``                ``s2.pop(``-``1``)``                ``root2 ``=` `root2.right ``                ``root1 ``=` `None`` ` `        ``# Both roots and both stacks are empty ``        ``else``:``            ``break`` ` `# A utility function to do inorder traversal ``def` `inorder(root):``    ``if` `root:``        ``inorder(root.left) ``        ``print``(root.key, end ``=` `" "``)``        ``inorder(root.right)`` ` `# A utility function to insert a new Node``# with given key in BST ``def` `insert(node, key):``     ` `    ``# If the tree is empty, return a new Node ``    ``if` `node ``=``=` `None``:``        ``return` `newNode(key) `` ` `    ``# Otherwise, recur down the tree ``    ``if` `key < node.key: ``        ``node.left ``=` `insert(node.left, key) ``    ``elif` `key > node.key: ``        ``node.right ``=` `insert(node.right, key)``         ` `    ``# return the (unchanged) Node pointer ``    ``return` `node`` ` `# Driver Code ``if` `__name__ ``=``=` `'__main__'``:``     ` `    ``# Create first tree as shown in example ``    ``root1 ``=` `None``    ``root1 ``=` `insert(root1, ``5``) ``    ``root1 ``=` `insert(root1, ``1``) ``    ``root1 ``=` `insert(root1, ``10``) ``    ``root1 ``=` `insert(root1, ``0``) ``    ``root1 ``=` `insert(root1, ``4``) ``    ``root1 ``=` `insert(root1, ``7``) ``    ``root1 ``=` `insert(root1, ``9``) `` ` `    ``# Create second tree as shown in example ``    ``root2 ``=` `None``    ``root2 ``=` `insert(root2, ``10``) ``    ``root2 ``=` `insert(root2, ``7``) ``    ``root2 ``=` `insert(root2, ``20``) ``    ``root2 ``=` `insert(root2, ``4``) ``    ``root2 ``=` `insert(root2, ``9``)`` ` `    ``print``(``"Tree 1 : "``) ``    ``inorder(root1) ``    ``print``()``     ` `    ``print``(``"Tree 2 : "``)``    ``inorder(root2)``    ``print``()`` ` `    ``print``(``"Common Nodes: "``) ``    ``printCommon(root1, root2)``     ` `# This code is contributed by PranchalK`

## C#

 `using` `System;``using` `System.Collections.Generic;`` ` `// C# program of iterative traversal based method to ``// find common elements in two BSTs. ``public` `class` `GfG``{`` ` `// A BST node ``public` `class` `Node``{``    ``public` `int` `key;``    ``public` `Node left, right;``}`` ` `// A utility function to create a new node ``public` `static` `Node newNode(``int` `ele)``{``    ``Node temp = ``new` `Node();``    ``temp.key = ele;``    ``temp.left = ``null``;``    ``temp.right = ``null``;``    ``return` `temp;``}`` ` `// Function two print common elements in given two trees ``public` `static` `void` `printCommon(Node root1, Node root2)``{``    ``Stack s1 = ``new` `Stack ();``    ``Stack s2 = ``new` `Stack ();`` ` `    ``while` `(``true``)``    ``{``        ``// push the Nodes of first tree in stack s1 ``        ``if` `(root1 != ``null``)``        ``{``            ``s1.Push(root1);``            ``root1 = root1.left;``        ``}`` ` `        ``// push the Nodes of second tree in stack s2 ``        ``else` `if` `(root2 != ``null``)``        ``{``            ``s2.Push(root2);``            ``root2 = root2.left;``        ``}`` ` `        ``// Both root1 and root2 are NULL here ``        ``else` `if` `(s1.Count > 0 && s2.Count > 0)``        ``{``            ``root1 = s1.Peek();``            ``root2 = s2.Peek();`` ` `            ``// If current keys in two trees are same ``            ``if` `(root1.key == root2.key)``            ``{``                ``Console.Write(root1.key + ``" "``);``                ``s1.Pop();``                ``s2.Pop();`` ` `                ``// move to the inorder successor ``                ``root1 = root1.right;``                ``root2 = root2.right;``            ``}`` ` `            ``else` `if` `(root1.key < root2.key)``            ``{``                ``// If Node of first tree is smaller, than that of ``                ``// second tree, then its obvious that the inorder ``                ``// successors of current Node can have same value ``                ``// as that of the second tree Node. Thus, we pop ``                ``// from s2 ``                ``s1.Pop();``                ``root1 = root1.right;`` ` `                ``// root2 is set to NULL, because we need ``                ``// new Nodes of tree 1 ``                ``root2 = ``null``;``            ``}``            ``else` `if` `(root1.key > root2.key)``            ``{``                ``s2.Pop();``                ``root2 = root2.right;``                ``root1 = ``null``;``            ``}``        ``}`` ` `        ``// Both roots and both stacks are empty ``        ``else``        ``{``            ``break``;``        ``}``    ``}``}`` ` `// A utility function to do inorder traversal ``public` `static` `void` `inorder(Node root)``{``    ``if` `(root != ``null``)``    ``{``        ``inorder(root.left);``        ``Console.Write(root.key + ``" "``);``        ``inorder(root.right);``    ``}``}`` ` `/* A utility function to insert a new Node with given key in BST */``public` `static` `Node insert(Node node, ``int` `key)``{``    ``/* If the tree is empty, return a new Node */``    ``if` `(node == ``null``)``    ``{``        ``return` `newNode(key);``    ``}`` ` `    ``/* Otherwise, recur down the tree */``    ``if` `(key < node.key)``    ``{``        ``node.left = insert(node.left, key);``    ``}``    ``else` `if` `(key > node.key)``    ``{``        ``node.right = insert(node.right, key);``    ``}`` ` `    ``/* return the (unchanged) Node pointer */``    ``return` `node;``}`` ` `// Driver program ``public` `static` `void` `Main(``string``[] args)``{``    ``// Create first tree as shown in example ``    ``Node root1 = ``null``;``    ``root1 = insert(root1, 5);``    ``root1 = insert(root1, 1);``    ``root1 = insert(root1, 10);``    ``root1 = insert(root1, 0);``    ``root1 = insert(root1, 4);``    ``root1 = insert(root1, 7);``    ``root1 = insert(root1, 9);`` ` `    ``// Create second tree as shown in example ``    ``Node root2 = ``null``;``    ``root2 = insert(root2, 10);``    ``root2 = insert(root2, 7);``    ``root2 = insert(root2, 20);``    ``root2 = insert(root2, 4);``    ``root2 = insert(root2, 9);`` ` `    ``Console.Write(``"Tree 1 : "` `+ ``"\n"``); ``    ``inorder(root1); ``    ``Console.WriteLine(); ``    ``Console.Write(``"Tree 2 : "` `+ ``"\n"``); ``    ``inorder(root2); ``    ``Console.WriteLine(); ``    ``Console.Write(``"Common Nodes: "` `+ ``"\n"``); `` ` `    ``printCommon(root1, root2);`` ` `}``}`` ` `// This code is contributed by Shrikant13`

Output:
`4 7 9 10`
• Complexity Analysis:
• Time Complexity: O(n+m).
Here ‘m’ and ‘n’ are number of nodes in first and second tree respectively,as we need to traverse both the trees.
• Auxiliary Space :Use of stack for storing values, at-most elements = ‘Height of tree’: O(h1+h2)

This article is contributed by Ekta Goel. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up