Iterative function to check if two trees are identical
Two trees are identical when they have same data and arrangement of data is also same. To identify if two trees are identical, we need to traverse both trees simultaneously, and while traversing we need to compare data and children of the trees.
Examples:
Input : Roots of below trees
10 10
/ \ /
5 6 5
Output : false
Input : Roots of below trees
10 10
/ \ / \
5 6 5 6
Output : true
We have discussed recursive solution here. In this article iterative solution is discussed.
The idea is to use level order traversal. We traverse both trees simultaneously and compare the data whenever we dequeue and item from queue. Below is the implementation of the idea.
C++
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int data;
struct Node *left, *right;
};
bool areIdentical(Node *root1, Node *root2)
{
if (root1==NULL && root2==NULL) return true ;
if (root1 == NULL) return false ;
if (root2 == NULL) return false ;
queue<Node *> q1, q2;
q1.push(root1);
q2.push(root2);
while (!q1.empty() && !q2.empty())
{
Node *n1 = q1.front();
Node *n2 = q2.front();
if (n1->data != n2->data)
return false ;
q1.pop(), q2.pop();
if (n1->left && n2->left)
{
q1.push(n1->left);
q2.push(n2->left);
}
else if (n1->left || n2->left)
return false ;
if (n1->right && n2->right)
{
q1.push(n1->right);
q2.push(n2->right);
}
else if (n1->right || n2->right)
return false ;
}
return true ;
}
Node* newNode( int data)
{
Node *temp = new Node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
int main()
{
Node *root1 = newNode(1);
root1->left = newNode(2);
root1->right = newNode(3);
root1->left->left = newNode(4);
root1->left->right = newNode(5);
Node *root2 = newNode(1);
root2->left = newNode(2);
root2->right = newNode(3);
root2->left->left = newNode(4);
root2->left->right = newNode(5);
areIdentical(root1, root2)? cout << "Yes"
: cout << "No" ;
return 0;
}
|
Java
import java.util.*;
class GfG {
static class Node
{
int data;
Node left, right;
}
static boolean areIdentical(Node root1, Node root2)
{
if (root1 == null && root2 == null ) return true ;
if (root1 == null || root2 == null ) return false ;
Queue<Node > q1 = new LinkedList<Node> ();
Queue<Node> q2 = new LinkedList<Node> ();
q1.add(root1);
q2.add(root2);
while (!q1.isEmpty() && !q2.isEmpty())
{
Node n1 = q1.peek();
Node n2 = q2.peek();
if (n1.data != n2.data)
return false ;
q1.remove();
q2.remove();
if (n1.left != null && n2.left != null )
{
q1.add(n1.left);
q2.add(n2.left);
}
else if (n1.left != null || n2.left != null )
return false ;
if (n1.right != null && n2.right != null )
{
q1.add(n1.right);
q2.add(n2.right);
}
else if (n1.right != null || n2.right != null )
return false ;
}
return true ;
}
static Node newNode( int data)
{
Node temp = new Node();
temp.data = data;
temp.left = null ;
temp.right = null ;
return temp;
}
public static void main(String[] args)
{
Node root1 = newNode( 1 );
root1.left = newNode( 2 );
root1.right = newNode( 3 );
root1.left.left = newNode( 4 );
root1.left.right = newNode( 5 );
Node root2 = newNode( 1 );
root2.left = newNode( 2 );
root2.right = newNode( 3 );
root2.left.left = newNode( 4 );
root2.left.right = newNode( 5 );
if (areIdentical(root1, root2) == true )
System.out.println( "Yes" );
else
System.out.println( "No" );
}
}
|
Python3
from queue import Queue
class newNode:
def __init__( self , data):
self .data = data
self .left = self .right = None
def areIdentical(root1, root2):
if (root1 and root2):
return True
if (root1 or root2):
return False
q1 = Queue()
q2 = Queue()
q1.put(root1)
q2.put(root2)
while ( not q1.empty() and not q2.empty()):
n1 = q1.queue[ 0 ]
n2 = q2.queue[ 0 ]
if (n1.data ! = n2.data):
return False
q1.get()
q2.get()
if (n1.left and n2.left):
q1.put(n1.left)
q2.put(n2.left)
elif (n1.left or n2.left):
return False
if (n1.right and n2.right):
q1.put(n1.right)
q2.put(n2.right)
elif (n1.right or n2.right):
return False
return True
if __name__ = = '__main__' :
root1 = newNode( 1 )
root1.left = newNode( 2 )
root1.right = newNode( 3 )
root1.left.left = newNode( 4 )
root1.left.right = newNode( 5 )
root2 = newNode( 1 )
root2.left = newNode( 2 )
root2.right = newNode( 3 )
root2.left.left = newNode( 4 )
root2.left.right = newNode( 5 )
if areIdentical(root1, root2):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
using System.Collections.Generic;
class GfG
{
class Node
{
public int data;
public Node left, right;
}
static bool areIdentical(Node root1, Node root2)
{
if (root1 == null && root2 == null )
return true ;
if (root1 == null || root2 == null )
return false ;
Queue<Node> q1 = new Queue<Node> ();
Queue<Node> q2 = new Queue<Node> ();
q1.Enqueue(root1);
q2.Enqueue(root2);
while (q1.Count != 0 && q2.Count != 0)
{
Node n1 = q1.Peek();
Node n2 = q2.Peek();
if (n1.data != n2.data)
return false ;
q1.Dequeue();
q2.Dequeue();
if (n1.left != null && n2.left != null )
{
q1.Enqueue(n1.left);
q2.Enqueue(n2.left);
}
else if (n1.left != null || n2.left != null )
return false ;
if (n1.right != null && n2.right != null )
{
q1.Enqueue(n1.right);
q2.Enqueue(n2.right);
}
else if (n1.right != null || n2.right != null )
return false ;
}
return true ;
}
static Node newNode( int data)
{
Node temp = new Node();
temp.data = data;
temp.left = null ;
temp.right = null ;
return temp;
}
public static void Main(String[] args)
{
Node root1 = newNode(1);
root1.left = newNode(2);
root1.right = newNode(3);
root1.left.left = newNode(4);
root1.left.right = newNode(5);
Node root2 = newNode(1);
root2.left = newNode(2);
root2.right = newNode(3);
root2.left.left = newNode(4);
root2.left.right = newNode(5);
if (areIdentical(root1, root2) == true )
Console.WriteLine( "Yes" );
else
Console.WriteLine( "No" );
}
}
|
Javascript
<script>
class Node
{
constructor()
{
this .data = 0;
this .left = null ;
this .right = null ;
}
}
function areIdentical(root1, root2)
{
if (root1 == null && root2 == null )
return true ;
if (root1 == null || root2 == null )
return false ;
var q1 = [];
var q2 = [];
q1.push(root1);
q2.push(root2);
while (q1.length != 0 && q2.length != 0)
{
var n1 = q1[0];
var n2 = q2[0];
if (n1.data != n2.data)
return false ;
q1.shift();
q2.shift();
if (n1.left != null && n2.left != null )
{
q1.push(n1.left);
q2.push(n2.left);
}
else if (n1.left != null || n2.left != null )
return false ;
if (n1.right != null && n2.right != null )
{
q1.push(n1.right);
q2.push(n2.right);
}
else if (n1.right != null || n2.right != null )
return false ;
}
return true ;
}
function newNode(data)
{
var temp = new Node();
temp.data = data;
temp.left = null ;
temp.right = null ;
return temp;
}
var root1 = newNode(1);
root1.left = newNode(2);
root1.right = newNode(3);
root1.left.left = newNode(4);
root1.left.right = newNode(5);
var root2 = newNode(1);
root2.left = newNode(2);
root2.right = newNode(3);
root2.left.left = newNode(4);
root2.left.right = newNode(5);
if (areIdentical(root1, root2) == true )
document.write( "Yes" );
else
document.write( "No" );
</script>
|
Time complexity of above solution is O(n + m) where m and n are number of nodes in two trees.
Space complexity: O(n) space for queue
Using Iterative Post-Order Traversal and Two Stacks:
The basic idea behind this approach is to traverse both trees in a postorder fashion iteratively, and compare their nodes one by one. We can use two stacks to do this. We start with pushing the root nodes of both trees onto their respective stacks.
Follow the steps to implement the idea:
- we repeat the following steps until both stacks are empty:
- Pop the top node from each stack.
- Compare the popped nodes. If they are not identical, return false.
- Push the right subtree of both nodes (if they exist) onto their respective stacks.
- Push the left subtree of both nodes (if they exist) onto their respective stacks.
Below is the implementation of the above approach:
C++
#include <iostream>
#include <stack>
using namespace std;
struct Node {
int data;
Node *left, *right;
Node( int x)
{
data = x;
left = right = NULL;
}
};
bool isIdentical(Node* r1, Node* r2)
{
stack<Node*> stack1, stack2;
while (r1 != NULL || !stack1.empty() || r2 != NULL
|| !stack2.empty()) {
while (r1 != NULL) {
stack1.push(r1);
r1 = r1->left;
}
while (r2 != NULL) {
stack2.push(r2);
r2 = r2->left;
}
if (stack1.size() != stack2.size())
return false ;
r1 = stack1.top();
stack1.pop();
r2 = stack2.top();
stack2.pop();
if (r1->data != r2->data)
return false ;
r1 = r1->right;
r2 = r2->right;
}
return true ;
}
int main()
{
Node* root1 = new Node(1);
root1->left = new Node(2);
root1->right = new Node(3);
root1->left->left = new Node(4);
root1->left->right = new Node(5);
Node* root2 = new Node(1);
root2->left = new Node(2);
root2->right = new Node(3);
root2->left->left = new Node(4);
root2->left->right = new Node(5);
if (isIdentical(root1, root2))
cout << "Both trees are identical" ;
else
cout << "Both trees are not identical" ;
return 0;
}
|
Java
import java.util.Stack;
class Node {
int data;
Node left, right;
Node( int x) {
data = x;
left = right = null ;
}
}
public class IdenticalBinaryTrees {
static boolean isIdentical(Node r1, Node r2) {
Stack<Node> stack1 = new Stack<>();
Stack<Node> stack2 = new Stack<>();
while (r1 != null || !stack1.empty() || r2 != null || !stack2.empty()) {
while (r1 != null ) {
stack1.push(r1);
r1 = r1.left;
}
while (r2 != null ) {
stack2.push(r2);
r2 = r2.left;
}
if (stack1.size() != stack2.size())
return false ;
r1 = stack1.pop();
r2 = stack2.pop();
if (r1.data != r2.data)
return false ;
r1 = r1.right;
r2 = r2.right;
}
return true ;
}
public static void main(String[] args) {
Node root1 = new Node( 1 );
root1.left = new Node( 2 );
root1.right = new Node( 3 );
root1.left.left = new Node( 4 );
root1.left.right = new Node( 5 );
Node root2 = new Node( 1 );
root2.left = new Node( 2 );
root2.right = new Node( 3 );
root2.left.left = new Node( 4 );
root2.left.right = new Node( 5 );
if (isIdentical(root1, root2))
System.out.println( "Both trees are identical" );
else
System.out.println( "Both trees are not identical" );
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def isIdentical(r1, r2):
stack1 = []
stack2 = []
while r1 or stack1 or r2 or stack2:
while r1:
stack1.append(r1)
r1 = r1.left
while r2:
stack2.append(r2)
r2 = r2.left
if len (stack1) ! = len (stack2):
return False
r1 = stack1.pop()
r2 = stack2.pop()
if r1.data ! = r2.data:
return False
r1 = r1.right
r2 = r2.right
return True
if __name__ = = '__main__' :
root1 = Node( 1 )
root1.left = Node( 2 )
root1.right = Node( 3 )
root1.left.left = Node( 4 )
root1.left.right = Node( 5 )
root2 = Node( 1 )
root2.left = Node( 2 )
root2.right = Node( 3 )
root2.left.left = Node( 4 )
root2.left.right = Node( 5 )
if isIdentical(root1, root2):
print ( "Both trees are identical" )
else :
print ( "Both trees are not identical" )
|
C#
using System;
using System.Collections.Generic;
class Node
{
public int data;
public Node left, right;
public Node( int x)
{
data = x;
left = right = null ;
}
}
class IterativePostorderTraversal
{
static bool IsIdentical(Node r1, Node r2)
{
Stack<Node> stack1 = new Stack<Node>();
Stack<Node> stack2 = new Stack<Node>();
while (r1 != null || stack1.Count > 0 || r2 != null || stack2.Count > 0)
{
while (r1 != null )
{
stack1.Push(r1);
r1 = r1.left;
}
while (r2 != null )
{
stack2.Push(r2);
r2 = r2.left;
}
if (stack1.Count != stack2.Count)
return false ;
r1 = stack1.Pop();
r2 = stack2.Pop();
if (r1.data != r2.data)
return false ;
r1 = r1.right;
r2 = r2.right;
}
return true ;
}
static void Main( string [] args)
{
Node root1 = new Node(1);
root1.left = new Node(2);
root1.right = new Node(3);
root1.left.left = new Node(4);
root1.left.right = new Node(5);
Node root2 = new Node(1);
root2.left = new Node(2);
root2.right = new Node(3);
root2.left.left = new Node(4);
root2.left.right = new Node(5);
if (IsIdentical(root1, root2))
Console.WriteLine( "Both trees are identical" );
else
Console.WriteLine( "Both trees are not identical" );
}
}
|
Javascript
class Node {
constructor(data) {
this .data = data;
this .left = null ;
this .right = null ;
}
}
function isIdentical(r1, r2) {
const stack1 = [];
const stack2 = [];
while (r1 || stack1.length > 0 || r2 || stack2.length > 0) {
while (r1) {
stack1.push(r1);
r1 = r1.left;
}
while (r2) {
stack2.push(r2);
r2 = r2.left;
}
if (stack1.length !== stack2.length)
return false ;
r1 = stack1.pop();
r2 = stack2.pop();
if (r1.data !== r2.data)
return false ;
r1 = r1.right;
r2 = r2.right;
}
return true ;
}
function main() {
const root1 = new Node(1);
root1.left = new Node(2);
root1.right = new Node(3);
root1.left.left = new Node(4);
root1.left.right = new Node(5);
const root2 = new Node(1);
root2.left = new Node(2);
root2.right = new Node(3);
root2.left.left = new Node(4);
root2.left.right = new Node(5);
if (isIdentical(root1, root2))
console.log( "Both trees are identical" );
else
console.log( "Both trees are not identical" );
}
main();
|
Output
Both trees are identical
Time Complexity: O(N) , The time complexity of the isIdentical function is O(n), where n is the total number of nodes in the trees. This is because we visit each node exactly once and perform a constant amount of work at each node.
Auxiliary Space: O(H) , The space complexity of the isIdentical function is O(h), where h is the maximum height of the two trees. This is because we use two stacks to keep track of the nodes in the two trees
This article is contributed by Ankur Lathiya .
Last Updated :
11 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...