Write a function to determine if two trees are identical or not:
Two trees are identical when they have the same data and the arrangement of data is also the same
Examples:
Input: 1 1
/ \ / \
2 3 2 3
/ /
4 4
Output: Both trees are identical
Input: 1 1
/ \ / \
2 3 5 3
/ /
4 4
Output: Trees are not identical
Approach: To solve the problem follow the below idea:
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
Follow the given steps to solve the problem:
- If both trees are empty then return 1(Base case)
- Else If both trees are non-empty
- Check data of the root nodes (tree1->data == tree2->data)
- Check left subtrees recursively
- Check right subtrees recursively
- If the above three statements are true then return 1
- Else return 0 (one is empty and the other is not)
Below is the implementation of this approach:
C++
#include <bits/stdc++.h>
using namespace std;
class node {
public :
int data;
node* left;
node* right;
};
node* newNode( int data)
{
node* Node = new node();
Node->data = data;
Node->left = NULL;
Node->right = NULL;
return (Node);
}
int identicalTrees(node* a, node* b)
{
if (a == NULL && b == NULL)
return 1;
if (a != NULL && b != NULL) {
return (a->data == b->data
&& identicalTrees(a->left, b->left)
&& identicalTrees(a->right, b->right));
}
return 0;
}
int main()
{
node* root1 = newNode(1);
node* root2 = newNode(1);
root1->left = newNode(2);
root1->right = newNode(3);
root1->left->left = newNode(4);
root1->left->right = newNode(5);
root2->left = newNode(2);
root2->right = newNode(3);
root2->left->left = newNode(4);
root2->left->right = newNode(5);
if (identicalTrees(root1, root2))
cout << "Both trees are identical." ;
else
cout << "Trees are not identical." ;
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* left;
struct node* right;
};
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);
}
int identicalTrees( struct node* a, struct node* b)
{
if (a == NULL && b == NULL)
return 1;
if (a != NULL && b != NULL) {
return (a->data == b->data
&& identicalTrees(a->left, b->left)
&& identicalTrees(a->right, b->right));
}
return 0;
}
int main()
{
struct node* root1 = newNode(1);
struct node* root2 = newNode(1);
root1->left = newNode(2);
root1->right = newNode(3);
root1->left->left = newNode(4);
root1->left->right = newNode(5);
root2->left = newNode(2);
root2->right = newNode(3);
root2->left->left = newNode(4);
root2->left->right = newNode(5);
if (identicalTrees(root1, root2))
printf ( "Both tree are identical." );
else
printf ( "Trees are not identical." );
getchar ();
return 0;
}
|
Java
class Node {
int data;
Node left, right;
Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree {
Node root1, root2;
boolean identicalTrees(Node a, Node b)
{
if (a == null && b == null )
return true ;
if (a != null && b != null )
return (a.data == b.data
&& identicalTrees(a.left, b.left)
&& identicalTrees(a.right, b.right));
return false ;
}
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root1 = new Node( 1 );
tree.root1.left = new Node( 2 );
tree.root1.right = new Node( 3 );
tree.root1.left.left = new Node( 4 );
tree.root1.left.right = new Node( 5 );
tree.root2 = new Node( 1 );
tree.root2.left = new Node( 2 );
tree.root2.right = new Node( 3 );
tree.root2.left.left = new Node( 4 );
tree.root2.left.right = new Node( 5 );
if (tree.identicalTrees(tree.root1, tree.root2))
System.out.println( "Both trees are identical" );
else
System.out.println( "Trees are not identical" );
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def identicalTrees(a, b):
if a is None and b is None :
return True
if a is not None and b is not None :
return ((a.data = = b.data) and
identicalTrees(a.left, b.left) and
identicalTrees(a.right, b.right))
return False
root1 = Node( 1 )
root2 = Node( 1 )
root1.left = Node( 2 )
root1.right = Node( 3 )
root1.left.left = Node( 4 )
root1.left.right = Node( 5 )
root2.left = Node( 2 )
root2.right = Node( 3 )
root2.left.left = Node( 4 )
root2.left.right = Node( 5 )
if __name__ = = "__main__" :
if identicalTrees(root1, root2):
print ( "Both trees are identical" )
else :
print ( "Trees are not identical" )
|
C#
using System;
public class Node {
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
public class BinaryTree {
public Node root1, root2;
public virtual bool identicalTrees(Node a, Node b)
{
if (a == null && b == null ) {
return true ;
}
if (a != null && b != null ) {
return (a.data == b.data
&& identicalTrees(a.left, b.left)
&& identicalTrees(a.right, b.right));
}
return false ;
}
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
tree.root1 = new Node(1);
tree.root1.left = new Node(2);
tree.root1.right = new Node(3);
tree.root1.left.left = new Node(4);
tree.root1.left.right = new Node(5);
tree.root2 = new Node(1);
tree.root2.left = new Node(2);
tree.root2.right = new Node(3);
tree.root2.left.left = new Node(4);
tree.root2.left.right = new Node(5);
if (tree.identicalTrees(tree.root1, tree.root2)) {
Console.WriteLine( "Both trees are identical" );
}
else {
Console.WriteLine( "Trees are not identical" );
}
}
}
|
Javascript
<script>
class Node
{
constructor(data) {
this .left = null ;
this .right = null ;
this .data = data;
}
}
let root1, root2;
function identicalTrees(a, b)
{
if (a == null && b == null )
return true ;
if (a != null && b != null )
return (a.data == b.data
&& identicalTrees(a.left, b.left)
&& identicalTrees(a.right, b.right));
return false ;
}
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);
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 (identicalTrees(root1, root2))
document.write( "Both trees are identical" );
else
document.write( "Trees are not identical" );
</script>
|
OutputBoth trees are identical.
Time Complexity: O(min(N, M)), Where N and M are the sizes of the trees
Auxiliary Space: O(log min(N, M)), due to auxiliary stack space used by recursion calls
Write a function to determine if two trees are identical or not by comparing their traversals:
To solve the problem follow the below idea:
If two trees are identical, their preorder, inorder and postorder traversals will also be the same
Note: For this, we can find one traversal, say inorder, and if it is the same for both the trees, can we say the given trees are identical? No, because we can have two trees with the same inorder traversal, still they can be non-identical.
See the below example:
Tree 1: 2 Tree 2: 1
/ \
1 2
Both the trees have inorder traversal as “2 1”, but they are not identical.
To tackle such edge cases, we should find all the traversal for both the trees and see if they are equal. If yes, the given trees are identical else not.
Below is the implementation of this approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Node {
public :
int data;
Node* left;
Node* right;
Node( int d)
{
this ->data = d;
this ->left = NULL;
this ->right = NULL;
}
};
void inOrder(Node* root, vector< int >& sol)
{
if (root == NULL)
return ;
inOrder(root->left, sol);
sol.push_back(root->data);
inOrder(root->right, sol);
}
void preOrder(Node* root, vector< int >& sol)
{
if (root == NULL)
return ;
sol.push_back(root->data);
preOrder(root->left, sol);
preOrder(root->right, sol);
}
void postOrder(Node* root, vector< int >& sol)
{
if (root == NULL)
return ;
postOrder(root->left, sol);
postOrder(root->right, sol);
sol.push_back(root->data);
}
bool isIdentical(Node* root1, Node* root2)
{
vector< int > res1;
vector< int > res2;
inOrder(root1, res1);
inOrder(root2, res2);
if (res1 != res2)
return false ;
res1.clear();
res2.clear();
preOrder(root1, res1);
preOrder(root2, res2);
if (res1 != res2)
return false ;
res1.clear();
res2.clear();
postOrder(root1, res1);
postOrder(root2, res2);
if (res1 != res2)
return false ;
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 the trees are identical." << endl;
}
else {
cout << "Given trees are not identical." << endl;
}
return 0;
}
|
Java
import java.io.*;
import java.util.*;
public class GFG {
static class Node {
int data;
Node left, right;
public Node( int data) { this .data = data; }
}
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 the trees are identical." );
}
else {
System.out.println(
"Given trees are not identical." );
}
}
static boolean isIdentical(Node root1, Node root2)
{
ArrayList<Integer> res1 = new ArrayList<Integer>();
ArrayList<Integer> res2 = new ArrayList<Integer>();
inOrder(root1, res1);
inOrder(root2, res2);
if (!res1.equals(res2))
return false ;
res1.clear();
res2.clear();
preOrder(root1, res1);
preOrder(root2, res2);
if (!res1.equals(res2))
return false ;
res1.clear();
res2.clear();
postOrder(root1, res1);
postOrder(root2, res2);
if (!res1.equals(res2))
return false ;
return true ;
}
static void inOrder(Node root, ArrayList<Integer> sol)
{
if (root == null )
return ;
inOrder(root.left, sol);
sol.add(root.data);
inOrder(root.right, sol);
}
static void preOrder(Node root, ArrayList<Integer> sol)
{
if (root == null )
return ;
sol.add(root.data);
preOrder(root.left, sol);
preOrder(root.right, sol);
}
static void postOrder(Node root, ArrayList<Integer> sol)
{
if (root == null )
return ;
postOrder(root.left, sol);
postOrder(root.right, sol);
sol.add(root.data);
}
}
|
Python3
class Node:
def __init__( self , key):
self .data = key
self .left = None
self .right = None
def inOrder(root, sol):
if root is None :
return
inOrder(root.left, sol)
sol.append(root.data)
inOrder(root.right, sol)
def preOrder(root, sol):
if root is None :
return
sol.append(root.data)
preOrder(root.left, sol)
preOrder(root.right, sol)
def postOrder(root, sol):
if root is None :
return
postOrder(root.left, sol)
postOrder(root.right, sol)
sol.append(root.data)
def isIdentical(root1, root2):
res1 = []
res2 = []
inOrder(root1, res1)
inOrder(root2, res2)
if res1 ! = res2:
return False
res1.clear()
res2.clear()
preOrder(root1, res1)
preOrder(root2, res2)
if res1 ! = res2:
return False
res1.clear()
res2.clear()
postOrder(root1, res1)
postOrder(root2, res2)
if res1 ! = res2:
return False
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 the trees are identical." )
else :
print ( "Given trees are not identical" )
|
C#
using System;
using System.Collections.Generic;
public class GFG {
class Node {
public int data;
public Node left, right;
public Node( int data) { this .data = data; }
}
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)) {
Console.WriteLine(
"Both the trees are identical." );
}
else {
Console.WriteLine(
"Given trees are not identical." );
}
}
static bool isIdentical(Node root1, Node root2)
{
List< int > res1 = new List< int >();
List< int > res2 = new List< int >();
inOrder(root1, res1);
inOrder(root2, res2);
if (!res1.Equals(res2))
return false ;
res1.Clear();
res2.Clear();
preOrder(root1, res1);
preOrder(root2, res2);
if (!res1.Equals(res2))
return false ;
res1.Clear();
res2.Clear();
postOrder(root1, res1);
postOrder(root2, res2);
if (!res1.Equals(res2))
return false ;
return true ;
}
static void inOrder(Node root, List< int > sol)
{
if (root == null )
return ;
inOrder(root.left, sol);
sol.Add(root.data);
inOrder(root.right, sol);
}
static void preOrder(Node root, List< int > sol)
{
if (root == null )
return ;
sol.Add(root.data);
preOrder(root.left, sol);
preOrder(root.right, sol);
}
static void postOrder(Node root, List< int > sol)
{
if (root == null )
return ;
postOrder(root.left, sol);
postOrder(root.right, sol);
sol.Add(root.data);
}
}
|
Javascript
class Node {
constructor(d) {
this .data = d;
this .left = null ;
this .right = null ;
}
}
function inOrder(root, sol) {
if (root == null ) return ;
inOrder(root.left, sol);
sol.push(root.data);
inOrder(root.right, sol);
}
function preOrder(root, sol) {
if (root == null ) return ;
sol.push(root.data);
preOrder(root.left, sol);
preOrder(root.right, sol);
}
function postOrder(root, sol) {
if (root == null ) return ;
postOrder(root.left, sol);
postOrder(root.right, sol);
sol.push(root.data);
}
function isIdentical(root1, root2) {
let res1 = [];
let res2 = [];
inOrder(root1, res1);
inOrder(root2, res2);
if (res1.toString() != res2.toString()) return false ;
res1 = [];
res2 = [];
preOrder(root1, res1);
preOrder(root2, res2);
if (res1.toString() != res2.toString()) return false ;
res1 = [];
res2 = [];
postOrder(root1, res1);
postOrder(root2, res2);
if (res1.toString() != res2.toString()) return false ;
return true ;
}
let 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);
let 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 the trees are identical." );
}
else {
console.log( "Given trees are not identical." );
}
|
OutputBoth the trees are identical.
Time complexity: O(N)
Auxiliary Space: O(N), since using auxiliary ArrayList and call stack
The Way We Can Determine Trees are Identical Only Using Pre-Order Traversal:
The Approach:
Here in this Approach we are storing preorder traversal of tree where we store zero(0)(we can store any another number so that we donot miss any node such as INT_MAX or -10000) for the null node and then we compare both vector if they are same then return true both the trees are identical.
C++
#include <bits/stdc++.h>
using namespace std;
class Node {
public :
int data;
Node* left;
Node* right;
Node( int d)
{
this ->data = d;
this ->left = NULL;
this ->right = NULL;
}
};
void preorder(Node* root,vector< int >&v){
if (root==NULL){
return ;
}
v.push_back(root->data);
if (root->left)preorder(root->left,v);
if (!root->left)v.push_back(0);
if (root->right)preorder(root->right,v);
if (!root->right)v.push_back(0);
}
bool isIdentical(Node* root1,Node*root2){
vector< int >v,x;
preorder(root1,v);
preorder(root2,x);
return v==x;
}
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 the trees are identical." << endl;
}
else {
cout << "Given trees are not identical." << endl;
}
}
|
Java
import java.util.Vector;
class Node {
int data;
Node left;
Node right;
Node( int d) {
this .data = d;
this .left = null ;
this .right = null ;
}
}
public class Main {
public void preorder(Node root, Vector<Integer> v) {
if (root == null ) {
return ;
}
v.add(root.data);
if (root.left != null ) {
preorder(root.left, v);
} else {
v.add( 0 );
}
if (root.right != null ) {
preorder(root.right, v);
} else {
v.add( 0 );
}
}
public boolean isIdentical(Node root1, Node root2) {
Vector<Integer> v = new Vector<Integer>();
Vector<Integer> x = new Vector<Integer>();
preorder(root1, v);
preorder(root2, x);
return v.equals(x);
}
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 );
Main main = new Main();
if (main.isIdentical(root1, root2)) {
System.out.println( "Both the trees are identical." );
} else {
System.out.println( "Given trees are not identical." );
}
}
}
|
Python3
class Node:
def __init__( self , d):
self .data = d
self .left = None
self .right = None
def preorder(root, v):
if root = = None :
return
v.append(root.data)
if root.left:
preorder(root.left, v)
else :
v.append( 0 )
if root.right:
preorder(root.right, v)
else :
v.append( 0 )
def isIdentical(root1, root2):
v = []
x = []
preorder(root1, v)
preorder(root2, x)
return v = = x
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 the trees are identical." )
else :
print ( "Given trees are not identical." )
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
public class Node{
public int data;
public Node left, right;
public Node( int item){
data = item;
left = right = null ;
}
}
public class BinaryTree {
public Node root1, root2;
public void preorder(Node root, List< int > v){
if (root == null ) return ;
v.Add(root.data);
if (root.left != null ) preorder(root.left, v);
if (root.left == null ) v.Add(0);
if (root.right != null ) preorder(root.right, v);
if (root.right == null ) v.Add(0);
}
public bool isIdentical(Node root1, Node root2){
List< int > v = new List< int >();
List< int > x = new List< int >();
preorder(root1, v);
preorder(root2, x);
return Enumerable.SequenceEqual(v, x);
}
public static void Main( string [] args){
BinaryTree tree = new BinaryTree();
tree.root1 = new Node(1);
tree.root1.left = new Node(2);
tree.root1.right = new Node(3);
tree.root1.left.left = new Node(4);
tree.root1.left.right = new Node(5);
tree.root2 = new Node(1);
tree.root2.left = new Node(2);
tree.root2.right = new Node(3);
tree.root2.left.left = new Node(4);
tree.root2.left.right = new Node(5);
if (tree.isIdentical(tree.root1, tree.root2)) {
Console.WriteLine( "Both the trees are identical." );
}
else {
Console.WriteLine( "Given trees are not identical." );
}
}
}
|
Javascript
class Node {
constructor(d) {
this .data = d;
this .left = null ;
this .right = null ;
}
}
function preorder( root, v){
if (root== null ){
return ;
}
v.push(root.data);
if (root.left)
preorder(root.left,v);
if (!root.left)
v.push(0);
if (root.right)
preorder(root.right,v);
if (!root.right)
v.push(0);
}
function isIdentical( root1,root2){
let v=[];
let x=[];
preorder(root1,v);
preorder(root2,x);
if (v.length!=x.length)
return 0;
for (let i=0; i<v.length; i++)
if (x[i]!=v[i])
return 0;
return 1;
}
let 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);
let 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 the trees are identical.\n" );
}
else {
console.log( "Given trees are not identical.\n" );
}
|
OutputBoth the trees are identical.
Time complexity: O(N)+O(M)
Auxiliary Space: O(N)+O(M) for vectors.
Using the Level Order traversal:
The idea behind this approach to solve the above problem is to traverse both trees level by level and compare the values of the nodes at each level. We can use a queue to store the nodes of both trees in a level order manner.
Follow the below steps to implement the above idea:
- Enqueue the root nodes of both trees into a queue.
- While the queue is not empty, dequeue the front nodes of both trees and compare their values.
- If the values are not equal, return false.
- If the values are equal, enqueue the left and right child nodes of both trees, if they exist, into the queue.
- Repeat steps 2-4 until either the queue becomes empty or we find two nodes with unequal values.
- If the queue becomes empty and we have not found any nodes with unequal values, return true indicating that the trees are identical.
Below is the implementation of the above approach:
C++
#include <iostream>
#include <queue>
using namespace std;
struct Node {
int data;
Node* left;
Node* right;
Node( int val)
{
data = val;
left = NULL;
right = NULL;
}
};
bool isIdentical(Node* root1, Node* root2)
{
if (root1 == NULL && root2 == NULL)
return true ;
if (root1 == NULL || root2 == NULL)
return false ;
queue<Node*> q1, q2;
q1.push(root1);
q2.push(root2);
while (!q1.empty() && !q2.empty()) {
Node* curr1 = q1.front();
q1.pop();
Node* curr2 = q2.front();
q2.pop();
if (curr1->data != curr2->data)
return false ;
if (curr1->left != NULL && curr2->left == NULL)
return false ;
if (curr1->left == NULL && curr2->left != NULL)
return false ;
if (curr1->right != NULL && curr2->right == NULL)
return false ;
if (curr1->right == NULL && curr2->right != NULL)
return false ;
if (curr1->left != NULL && curr2->left != NULL) {
q1.push(curr1->left);
q2.push(curr2->left);
}
if (curr1->right != NULL && curr2->right != NULL) {
q1.push(curr1->right);
q2.push(curr2->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 << "The trees are identical" << endl;
else
cout << "The trees are not identical" << endl;
return 0;
}
|
Java
import java.util.LinkedList;
import java.util.Queue;
class Node {
int data;
Node left;
Node right;
Node( int val)
{
data = val;
left = null ;
right = null ;
}
}
public class IdenticalTrees {
public static boolean isIdentical(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 curr1 = q1.poll();
Node curr2 = q2.poll();
if (curr1.data != curr2.data) {
return false ;
}
if (curr1.left != null && curr2.left == null
|| curr1.left == null
&& curr2.left != null ) {
return false ;
}
if (curr1.right != null && curr2.right == null
|| curr1.right == null
&& curr2.right != null ) {
return false ;
}
if (curr1.left != null && curr2.left != null ) {
q1.add(curr1.left);
q2.add(curr2.left);
}
if (curr1.right != null
&& curr2.right != null ) {
q1.add(curr1.right);
q2.add(curr2.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( "The trees are identical" );
}
else {
System.out.println(
"The trees are not identical" );
}
}
}
|
Python3
from queue import Queue
class Node:
def __init__( self , val):
self .data = val
self .left = None
self .right = None
def isIdentical(root1, root2):
if not root1 and not root2:
return True
if not root1 or not root2:
return False
q1 = Queue()
q2 = Queue()
q1.put(root1)
q2.put(root2)
while not q1.empty() and not q2.empty():
curr1 = q1.get()
curr2 = q2.get()
if curr1.data ! = curr2.data:
return False
if (curr1.left and not curr2.left) or ( not curr1.left and curr2.left):
return False
if (curr1.right and not curr2.right) or ( not curr1.right and curr2.right):
return False
if curr1.left and curr2.left:
q1.put(curr1.left)
q2.put(curr2.left)
if curr1.right and curr2.right:
q1.put(curr1.right)
q2.put(curr2.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 ( "The trees are identical" )
else :
print ( "The trees are not identical" )
|
C#
using System;
using System.Collections.Generic;
public class Node {
public int data;
public Node left;
public Node right;
public Node( int val)
{
data = val;
left = null ;
right = null ;
}
};
public class Gfg {
public static bool isIdentical(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 curr1 = q1.Dequeue();
Node curr2 = q2.Dequeue();
if (curr1.data != curr2.data)
return false ;
if (curr1.left != null && curr2.left == null )
return false ;
if (curr1.left == null && curr2.left != null )
return false ;
if (curr1.right != null && curr2.right == null )
return false ;
if (curr1.right == null && curr2.right != null )
return false ;
if (curr1.left != null && curr2.left != null ) {
q1.Enqueue(curr1.left);
q2.Enqueue(curr2.left);
}
if (curr1.right != null && curr2.right != null ) {
q1.Enqueue(curr1.right);
q2.Enqueue(curr2.right);
}
}
return true ;
}
static void 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))
Console.WriteLine( "The trees are identical" );
else
Console.WriteLine( "The trees are not identical" );
}
}
|
Javascript
class Node {
constructor(val) {
this .data = val;
this .left = null ;
this .right = null ;
}
}
function isIdentical(root1, root2) {
if (!root1 && !root2)
return true ;
if (!root1 || !root2)
return false ;
const q1 = [],
q2 = [];
q1.push(root1);
q2.push(root2);
while (q1.length && q2.length) {
const curr1 = q1.shift();
const curr2 = q2.shift();
if (curr1.data !== curr2.data)
return false ;
if (curr1.left && !curr2.left)
return false ;
if (!curr1.left && curr2.left)
return false ;
if (curr1.right && !curr2.right)
return false ;
if (!curr1.right && curr2.right)
return false ;
if (curr1.left && curr2.left) {
q1.push(curr1.left);
q2.push(curr2.left);
}
if (curr1.right && curr2.right) {
q1.push(curr1.right);
q2.push(curr2.right);
}
}
return true ;
}
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( "The trees are identical" );
else
console.log( "The trees are not identical" );
|
OutputThe trees are identical
Time complexity: O(N) , the time complexity will be proportional to the total number of nodes.
Auxiliary Space: O(N), The auxiliary space complexity of the level order traversal approach is O(n), where n is the total number of nodes in both trees.
Using the Morris traversal:
The basic idea behind the Morris traversal approach to solve the problem of checking if two binary trees are identical is to use the Morris traversal algorithm to traverse both trees in-order simultaneously, and compare the nodes visited at each step.
Follow the steps to implement the above idea:
- Check if both trees are empty. If they are, return true. If only one of them is empty, return false.
- Perform the Morris traversal for in-order traversal of both trees simultaneously. At each step, compare the nodes visited in both trees.
- If at any step, the nodes visited in both trees are not equal, return false.
- If we reach the end of both trees simultaneously (i.e., both nodes are NULL), return true.
Below is the implementation of the above idea:
C++
#include <iostream>
using namespace std;
struct Node {
int data;
Node *left, *right;
Node( int x)
{
data = x;
left = right = NULL;
}
};
bool isIdentical(Node* r1, Node* r2)
{
if (r1 == NULL && r2 == NULL)
return true ;
if (r1 == NULL
|| r2 == NULL)
return false ;
while (r1 != NULL && r2 != NULL) {
if (r1->data
!= r2->data)
return false ;
if (r1->left
== NULL) {
r1 = r1->right;
}
else {
Node* pre = r1->left;
while (pre->right != NULL
&& pre->right
!= r1)
pre = pre->right;
if (pre->right
== NULL) {
pre->right = r1;
r1 = r1->left;
}
else {
pre->right = NULL;
r1 = r1->right;
}
}
if (r2->left == NULL) {
r2 = r2->right;
}
else {
Node* pre = r2->left;
while (pre->right != NULL && pre->right != r2)
pre = pre->right;
if (pre->right == NULL) {
pre->right = r2;
r2 = r2->left;
}
else {
pre->right = NULL;
r2 = r2->right;
}
}
}
return (r1 == NULL
&& r2 == NULL);
}
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
class Node {
int data;
Node left, right;
Node( int item) {
data = item;
left = right = null ;
}
}
public class IdenticalBinaryTrees {
public static boolean isIdentical(Node r1, Node r2) {
if (r1 == null && r2 == null )
return true ;
if (r1 == null || r2 == null )
return false ;
while (r1 != null && r2 != null ) {
if (r1.data != r2.data)
return false ;
if (r1.left == null ) {
r1 = r1.right;
} else {
Node pre = r1.left;
while (pre.right != null && pre.right != r1)
pre = pre.right;
if (pre.right == null ) {
pre.right = r1;
r1 = r1.left;
} else {
pre.right = null ;
r1 = r1.right;
}
}
if (r2.left == null ) {
r2 = r2.right;
} else {
Node pre = r2.left;
while (pre.right != null && pre.right != r2)
pre = pre.right;
if (pre.right == null ) {
pre.right = r2;
r2 = r2.left;
} else {
pre.right = null ;
r2 = r2.right;
}
}
}
return (r1 == null && r2 == null );
}
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 , x):
self .data = x
self .left = None
self .right = None
def isIdentical(r1, r2):
if not r1 and not r2:
return True
if not r1 or not r2:
return False
while r1 and r2:
if r1.data ! = r2.data:
return False
if not r1.left:
r1 = r1.right
else :
pre = r1.left
while pre.right and pre.right ! = r1:
pre = pre.right
if not pre.right:
pre.right = r1
r1 = r1.left
else :
pre.right = None
r1 = r1.right
if not r2.left:
r2 = r2.right
else :
pre = r2.left
while pre.right and pre.right ! = r2:
pre = pre.right
if not pre.right:
pre.right = r2
r2 = r2.left
else :
pre.right = None
r2 = r2.right
return not r1 and not r2
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;
public class Node
{
public int data;
public Node left, right;
public Node( int x)
{
data = x;
left = right = null ;
}
}
public class IdenticalTrees
{
public static bool IsIdentical(Node r1, Node r2)
{
if (r1 == null && r2 == null )
return true ;
if (r1 == null || r2 == null )
return false ;
while (r1 != null && r2 != null )
{
if (r1.data != r2.data)
return false ;
if (r1.left == null )
{
r1 = r1.right;
}
else
{
Node pre = r1.left;
while (pre.right != null && pre.right != r1)
pre = pre.right;
if (pre.right == null )
{
pre.right = r1;
r1 = r1.left;
}
else
{
pre.right = null ;
r1 = r1.right;
}
}
if (r2.left == null )
{
r2 = r2.right;
}
else
{
Node pre = r2.left;
while (pre.right != null && pre.right != r2)
pre = pre.right;
if (pre.right == null )
{
pre.right = r2;
r2 = r2.left;
}
else
{
pre.right = null ;
r2 = r2.right;
}
}
}
return r1 == null && r2 == null ;
}
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))
Console.WriteLine( "Both trees are identical" );
else
Console.WriteLine( "Both trees are not identical" );
}
}
|
OutputBoth trees are identical
Time Complexity: O(N) ,The time complexity of the Morris traversal approach for checking if two binary trees are identical is O(n), where n is the total number of nodes in the trees. This is because each node is visited only once, and the traversal does not involve any recursion or extra data structures.
Auxiliary Space: O(1) , The space complexity of the Morris traversal approach is O(1), which means that the space required by the algorithm is constant and does not depend on the size of the input. This is because the traversal only requires a few pointers to the tree nodes and does not use any additional data structures, such as stacks or queues, to store intermediate results.
Related Article: Iterative function to check if two trees are identical.