Given two Binary Trees, check whether they are isomorphic or not. Two trees are considered isomorphic if one can be transformed into the other by performing a series of flips, where a flip means swapping the left and right children of a node. These swaps can be applied to any number of nodes at any level.
Note:
If two trees are the same (same structure and node values), they are isomorphic.
Two empty trees are isomorphic.
If the root node values of both trees differ, they are not isomorphic.
Examples:
Input:
Output: True Explanation: The above two trees are isomorphic with following sub-trees flipped: 2 and 3, NULL and 6, 7 and 8.
The idea is to traverse both trees recursively, comparing the nodes n1 and n2. Their data must be the same, and their subtrees must either be identical or mirror images (flipped). This ensures that the trees are structurally isomorphic.
Let the current internal nodes of the two trees be n1 and n2. For the subtrees rooted at n1 and n2 to be isomorphic, the following conditions must hold:
The data of n1 and n2 must be the same.
One of the following two conditions must be true for the children of n1 and n2:
The left of n1 is isomorphic to the left of n2, and the right of n1 is isomorphic to the right of n2.
The left of n1 is isomorphic to the right of n2, and the right of n1 is isomorphic to the left of n2.
This ensures that the trees are either structurally identical or have been "flipped" at some levels while still being isomorphic.
C++
usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){data=x;left=right=nullptr;}};// Function to check if two trees are isomorphicboolisIsomorphic(Node*root1,Node*root2){// Both roots are NULL, trees are isomorphic// by definitionif(root1==nullptr&&root2==nullptr){returntrue;}// Exactly one of the root1 and root2 is NULL,// trees not isomorphicif(root1==nullptr||root2==nullptr){returnfalse;}// If the data doesn't match, trees// are not isomorphicif(root1->data!=root2->data){returnfalse;}// Check if the trees are isomorphic by// considering the two cases:// Case 1: The subtrees have not been flipped// Case 2: The subtrees have been flippedreturn(isIsomorphic(root1->left,root2->left)&&isIsomorphic(root1->right,root2->right))||(isIsomorphic(root1->left,root2->right)&&isIsomorphic(root1->right,root2->left));}intmain(){// Representation of input binary tree 1// 1// / \ // 2 3// / \ /// 4 5 6// / \ // 7 8Node*root1=newNode(1);root1->left=newNode(2);root1->right=newNode(3);root1->left->left=newNode(4);root1->left->right=newNode(5);root1->right->left=newNode(6);root1->left->right->left=newNode(7);root1->left->right->right=newNode(8);// Representation of input binary tree 2// 1// / \ // 3 2// \ / \ // 6 4 5// / \ // 8 7Node*root2=newNode(1);root2->left=newNode(3);root2->right=newNode(2);root2->left->right=newNode(6);root2->right->left=newNode(4);root2->right->right=newNode(5);root2->right->right->left=newNode(8);root2->right->right->right=newNode(7);if(isIsomorphic(root1,root2)){cout<<"True\n";}else{cout<<"False\n";}return0;}
Java
classNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGfG{// Function to check if two trees are isomorphicstaticbooleanisIsomorphic(Noderoot1,Noderoot2){// Both roots are NULL, trees are// isomorphic by definitionif(root1==null&&root2==null){returntrue;}// Exactly one of the root1 and root2 is NULL,// trees not isomorphicif(root1==null||root2==null){returnfalse;}// If the data doesn't match, trees are not// isomorphicif(root1.data!=root2.data){returnfalse;}// Check if the trees are isomorphic by// considering the two cases:// Case 1: The subtrees have not been flipped// Case 2: The subtrees have been flippedreturn(isIsomorphic(root1.left,root2.left)&&isIsomorphic(root1.right,root2.right))||(isIsomorphic(root1.left,root2.right)&&isIsomorphic(root1.right,root2.left));}publicstaticvoidmain(String[]args){// Representation of input binary tree 1// 1// / \// 2 3// / \ /// 4 5 6// / \// 7 8Noderoot1=newNode(1);root1.left=newNode(2);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(5);root1.right.left=newNode(6);root1.left.right.left=newNode(7);root1.left.right.right=newNode(8);// Representation of input binary tree 2// 1// / \// 3 2// \ / \// 6 4 5// / \// 8 7Noderoot2=newNode(1);root2.left=newNode(3);root2.right=newNode(2);root2.left.right=newNode(6);root2.right.left=newNode(4);root2.right.right=newNode(5);root2.right.right.left=newNode(8);root2.right.right.right=newNode(7);if(isIsomorphic(root1,root2)){System.out.println("True");}else{System.out.println("False");}}}
Python
classNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Function to check if two trees are isomorphicdefisIsomorphic(root1,root2):# Both roots are None → isomorphicifroot1isNoneandroot2isNone:returnTrue# One is None → not isomorphicifroot1isNoneorroot2isNone:returnFalse# Data mismatch → not isomorphicifroot1.data!=root2.data:returnFalse# Check both cases: no flip OR flipreturn(isIsomorphic(root1.left,root2.left)andisIsomorphic(root1.right,root2.right))or \
(isIsomorphic(root1.left,root2.right)andisIsomorphic(root1.right,root2.left))if__name__=="__main__":# Representation of input binary tree 1# 1# / \# 2 3# / \ /# 4 5 6# / \# 7 8root1=Node(1)root1.left=Node(2)root1.right=Node(3)root1.left.left=Node(4)root1.left.right=Node(5)root1.right.left=Node(6)root1.left.right.left=Node(7)root1.left.right.right=Node(8)# Representation of input binary tree 2# 1# / \# 3 2# \ / \# 6 4 5# / \# 8 7root2=Node(1)root2.left=Node(3)root2.right=Node(2)root2.left.right=Node(6)root2.right.left=Node(4)root2.right.right=Node(5)root2.right.right.left=Node(8)root2.right.right.right=Node(7)ifisIsomorphic(root1,root2):print("True")else:print("False")
C#
usingSystem;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGfG{// Function to check if two trees are isomorphicstaticboolisIsomorphic(Noderoot1,Noderoot2){// Both roots are null, trees are// isomorphic by definitionif(root1==null&&root2==null){returntrue;}// Exactly one of the root1 and root2 is null,// trees not isomorphicif(root1==null||root2==null){returnfalse;}// If the data doesn't match, trees are not// isomorphicif(root1.data!=root2.data){returnfalse;}// Check if the trees are isomorphic by// considering the two cases:// Case 1: The subtrees have not been flipped// Case 2: The subtrees have been flippedreturn(isIsomorphic(root1.left,root2.left)&&isIsomorphic(root1.right,root2.right))||(isIsomorphic(root1.left,root2.right)&&isIsomorphic(root1.right,root2.left));}staticvoidMain(string[]args){// Representation of input binary tree 1// 1// / \// 2 3// / \ /// 4 5 6// / \// 7 8Noderoot1=newNode(1);root1.left=newNode(2);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(5);root1.right.left=newNode(6);root1.left.right.left=newNode(7);root1.left.right.right=newNode(8);// Representation of input binary tree 2// 1// / \// 3 2// \ / \// 6 4 5// / \// 8 7Noderoot2=newNode(1);root2.left=newNode(3);root2.right=newNode(2);root2.left.right=newNode(6);root2.right.left=newNode(4);root2.right.right=newNode(5);root2.right.right.left=newNode(8);root2.right.right.right=newNode(7);if(isIsomorphic(root1,root2)){Console.WriteLine("True");}else{Console.WriteLine("False");}}}
JavaScript
classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Function to check if two trees are isomorphicfunctionisIsomorphic(root1,root2){// Both roots are null, trees are isomorphic// by definitionif(root1===null&&root2===null){returntrue;}// Exactly one of the root1 and root2 is null,// trees not isomorphicif(root1===null||root2===null){returnfalse;}// If the data doesn't match, trees are not isomorphicif(root1.data!==root2.data){returnfalse;}// Check if the trees are isomorphic by // considering the two cases:// Case 1: The subtrees have not been flipped// Case 2: The subtrees have been flippedreturn(isIsomorphic(root1.left,root2.left)&&isIsomorphic(root1.right,root2.right))||(isIsomorphic(root1.left,root2.right)&&isIsomorphic(root1.right,root2.left));}// Representation of input binary tree 1// 1// / \// 2 3// / \ /// 4 5 6// / \// 7 8letroot1=newNode(1);root1.left=newNode(2);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(5);root1.right.left=newNode(6);root1.left.right.left=newNode(7);root1.left.right.right=newNode(8);// Representation of input binary tree 2// 1// / \// 3 2// \ / \// 6 4 5// / \// 8 7letroot2=newNode(1);root2.left=newNode(3);root2.right=newNode(2);root2.left.right=newNode(6);root2.right.left=newNode(4);root2.right.right=newNode(5);root2.right.right.left=newNode(8);root2.right.right.right=newNode(7);if(isIsomorphic(root1,root2)){console.log("True");}else{console.log("False");}
Output
True
Using Iteration - O(n) Time and O(n) Space
The idea is to traverse the first tree using level-order traversal (BFS) and store all parent-child relationships in a map. Each entry in the map represents a pair of (child node value, parent node value).
After that, we traverse the second tree and verify whether every such parent-child relationship exists in the map. If any relationship is missing, the trees cannot be isomorphic.
This approach works because even if we flip nodes (swap left and right children), the parent-child relationship remains unchanged, only their positions change.
Example: Consider the following two Binary trees, T1 and T2:
Step 1: Traverse Tree 1 (Level-order BFS)
We traverse the first tree level by level and record all parent-child pairs in a map or set.
Each pair consists of a child node value and its parent node value; the order of children doesn’t matter, only the parent-child relationship does.
Step 2: Traverse Tree 2 and check pairs
For Tree 2, the generated parent-child pairs are (3,1), (2,1), (6,3), (4,2), (5,2), (8,5), (7,5).
By checking each pair against the map from Tree 1, we find that all pairs exist, confirming that the trees are isomorphic.
Step 3: Why this works with flips
Left and right children can be swapped; parent-child pairs remain unchanged.
Example: Node 5 - children (7,8) in Tree 1; (8,7) in Tree 2.
Order of children doesn’t matter.
BFS + parent-child pairs preserve tree structure despite flips.
C++
usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){data=x;left=right=nullptr;}};// Helper function to check if the second// tree is isomorphicboolCheckTree(Node*root2,map<pair<int,int>,bool>&visited){// If root of the second tree is not visitedif(visited[{root2->data,-1}]==false){returnfalse;}queue<Node*>q;q.push(root2);// Traverse the second treewhile(!q.empty()){Node*curr=q.front();q.pop();if(curr->left){// If the left child has not been visitedif(visited[{curr->left->data,curr->data}]==false){returnfalse;}q.push(curr->left);}if(curr->right){// If the right child has not been visitedif(visited[{curr->right->data,curr->data}]==false){returnfalse;}q.push(curr->right);}}returntrue;}// Main function to check if two trees are isomorphicboolisIsomorphic(Node*root1,Node*root2){map<pair<int,int>,bool>visited;// Mark the root of the first tree as visitedvisited[{root1->data,-1}]=true;queue<Node*>q;q.push(root1);// Traverse the first tree and mark nodes as visitedwhile(!q.empty()){Node*curr=q.front();q.pop();if(curr->left){visited[{curr->left->data,curr->data}]=true;q.push(curr->left);}if(curr->right){visited[{curr->right->data,curr->data}]=true;q.push(curr->right);}}// Use the helper function to check the second treereturnCheckTree(root2,visited);}intmain(){// Representation of input binary tree 1// 1// / \ // 2 3// / \ / // 4 5 6// / \ // 7 8Node*root1=newNode(1);root1->left=newNode(2);root1->right=newNode(3);root1->left->left=newNode(4);root1->left->right=newNode(5);root1->right->left=newNode(6);root1->left->right->left=newNode(7);root1->left->right->right=newNode(8);// Representation of input binary tree 2// 1// / \ // 3 2// \ / \ // 6 4 5// / \ // 8 7Node*root2=newNode(1);root2->left=newNode(3);root2->right=newNode(2);root2->left->left=newNode(6);root2->right->left=newNode(4);root2->right->right=newNode(5);root2->right->right->left=newNode(8);root2->right->right->right=newNode(7);if(isIsomorphic(root1,root2)){cout<<"True\n";}else{cout<<"False\n";}return0;}
Java
importjava.util.Queue;importjava.util.LinkedList;importjava.util.Map;importjava.util.HashMap;importjava.util.Objects;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}// Pair class to store (child, parent)classPair{intfirst,second;Pair(intfirst,intsecond){this.first=first;this.second=second;}@Overridepublicbooleanequals(Objectobj){if(this==obj)returntrue;if(obj==null||getClass()!=obj.getClass())returnfalse;Pairp=(Pair)obj;returnfirst==p.first&&second==p.second;}@OverridepublicinthashCode(){returnObjects.hash(first,second);}}classGFG{// Helper function to check if the second// tree is isomorphicstaticbooleanCheckTree(Noderoot2,Map<Pair,Boolean>visited){// If root of the second tree is not visitedif(!visited.containsKey(newPair(root2.data,-1))){returnfalse;}Queue<Node>q=newLinkedList<>();q.add(root2);// Traverse the second treewhile(!q.isEmpty()){Nodecurr=q.poll();if(curr.left!=null){// If the left child has not been visitedif(!visited.containsKey(newPair(curr.left.data,curr.data))){returnfalse;}q.add(curr.left);}if(curr.right!=null){// If the right child has not been visitedif(!visited.containsKey(newPair(curr.right.data,curr.data))){returnfalse;}q.add(curr.right);}}returntrue;}// Main function to check if two trees are isomorphicstaticbooleanisIsomorphic(Noderoot1,Noderoot2){Map<Pair,Boolean>visited=newHashMap<>();// Mark the root of the first tree as visitedvisited.put(newPair(root1.data,-1),true);Queue<Node>q=newLinkedList<>();q.add(root1);// Traverse the first tree and mark nodes as visitedwhile(!q.isEmpty()){Nodecurr=q.poll();if(curr.left!=null){visited.put(newPair(curr.left.data,curr.data),true);q.add(curr.left);}if(curr.right!=null){visited.put(newPair(curr.right.data,curr.data),true);q.add(curr.right);}}// Use the helper function to check the second treereturnCheckTree(root2,visited);}publicstaticvoidmain(String[]args){// Representation of input binary tree 1// 1// / \// 2 3// / \ /// 4 5 6// / \// 7 8Noderoot1=newNode(1);root1.left=newNode(2);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(5);root1.right.left=newNode(6);root1.left.right.left=newNode(7);root1.left.right.right=newNode(8);// Representation of input binary tree 2// 1// / \// 3 2// \ / \// 6 4 5// / \// 8 7Noderoot2=newNode(1);root2.left=newNode(3);root2.right=newNode(2);root2.left.left=newNode(6);root2.right.left=newNode(4);root2.right.right=newNode(5);root2.right.right.left=newNode(8);root2.right.right.right=newNode(7);if(isIsomorphic(root1,root2)){System.out.println("True");}else{System.out.println("False");}}}
Python
fromcollectionsimportdequeclassNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Helper function to check if the second tree is isomorphicdefcheck_tree(root2,visited):if(root2.data,-1)notinvisited:returnFalsequeue=[root2]whilequeue:curr=queue.pop(0)ifcurr.left:if(curr.left.data,curr.data)notinvisited:returnFalsequeue.append(curr.left)ifcurr.right:if(curr.right.data,curr.data)notinvisited:returnFalsequeue.append(curr.right)returnTrue# Main function to check if two trees are isomorphicdefisIsomorphic(root1,root2):visited=set()# Mark the root of the first tree as visitedvisited.add((root1.data,-1))queue=[root1]# Traverse the first tree and mark nodes as visitedwhilequeue:curr=queue.pop(0)ifcurr.left:visited.add((curr.left.data,curr.data))queue.append(curr.left)ifcurr.right:visited.add((curr.right.data,curr.data))queue.append(curr.right)# Use the helper function to check the second treereturncheck_tree(root2,visited)if__name__=="__main__":# Representation of input binary tree 1# 1# / \# 2 3# / \ /# 4 5 6# / \# 7 8root1=Node(1)root1.left=Node(2)root1.right=Node(3)root1.left.left=Node(4)root1.left.right=Node(5)root1.right.left=Node(6)root1.left.right.left=Node(7)root1.left.right.right=Node(8)# Representation of input binary tree 2# 1# / \# 3 2# \ / \# 6 4 5# / \# 8 7root2=Node(1)root2.left=Node(3)root2.right=Node(2)root2.left.right=Node(6)root2.right.left=Node(4)root2.right.right=Node(5)root2.right.right.left=Node(8)root2.right.right.right=Node(7)ifisIsomorphic(root1,root2):print("True")else:print("False")
C#
usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}// Pair class to store (child, parent)classPair{publicintFirst,Second;publicPair(intfirst,intsecond){First=first;Second=second;}publicoverrideboolEquals(objectobj){if(this==obj)returntrue;if(obj==null||obj.GetType()!=GetType())returnfalse;Pairp=(Pair)obj;returnFirst==p.First&&Second==p.Second;}publicoverrideintGetHashCode(){returnHashCode.Combine(First,Second);}}classGFG{// Helper function to check if the second tree is isomorphicstaticboolCheckTree(Noderoot2,Dictionary<Pair,bool>visited){// If root of the second tree is not visitedif(!visited.ContainsKey(newPair(root2.data,-1)))returnfalse;Queue<Node>q=newQueue<Node>();q.Enqueue(root2);// Traverse the second treewhile(q.Count>0){Nodecurr=q.Dequeue();if(curr.left!=null){// If the left child has not been visitedif(!visited.ContainsKey(newPair(curr.left.data,curr.data)))returnfalse;q.Enqueue(curr.left);}if(curr.right!=null){// If the right child has not been visitedif(!visited.ContainsKey(newPair(curr.right.data,curr.data)))returnfalse;q.Enqueue(curr.right);}}returntrue;}// Main function to check if two trees are isomorphicstaticboolisIsomorphic(Noderoot1,Noderoot2){Dictionary<Pair,bool>visited=newDictionary<Pair,bool>();// Mark the root of the first tree as visitedvisited[newPair(root1.data,-1)]=true;Queue<Node>q=newQueue<Node>();q.Enqueue(root1);// Traverse the first tree and mark nodes as visitedwhile(q.Count>0){Nodecurr=q.Dequeue();if(curr.left!=null){visited[newPair(curr.left.data,curr.data)]=true;q.Enqueue(curr.left);}if(curr.right!=null){visited[newPair(curr.right.data,curr.data)]=true;q.Enqueue(curr.right);}}// Use the helper function to check the second treereturnCheckTree(root2,visited);}staticvoidMain(string[]args){// Representation of input binary tree 1// 1// / \// 2 3// / \ /// 4 5 6// / \// 7 8Noderoot1=newNode(1);root1.left=newNode(2);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(5);root1.right.left=newNode(6);root1.left.right.left=newNode(7);root1.left.right.right=newNode(8);// Representation of input binary tree 2// 1// / \// 3 2// \ / \// 6 4 5// / \// 8 7Noderoot2=newNode(1);root2.left=newNode(3);root2.right=newNode(2);root2.left.right=newNode(6);root2.right.left=newNode(4);root2.right.right=newNode(5);root2.right.right.left=newNode(8);root2.right.right.right=newNode(7);if(isIsomorphic(root1,root2))Console.WriteLine("True");elseConsole.WriteLine("False");}}
JavaScript
classNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Pair class to store (child, parent)classPair{constructor(first,second){this.first=first;this.second=second;}// Define equality for Map keysequals(other){returnotherinstanceofPair&&this.first===other.first&&this.second===other.second;}// Generate string key for MaptoString(){return`${this.first},${this.second}`;}}// Helper function to check if the second tree is isomorphicfunctioncheckTree(root2,visited){if(!visited.has(newPair(root2.data,-1).toString())){returnfalse;}constqueue=[root2];while(queue.length>0){constcurr=queue.shift();if(curr.left){if(!visited.has(newPair(curr.left.data,curr.data).toString())){returnfalse;}queue.push(curr.left);}if(curr.right){if(!visited.has(newPair(curr.right.data,curr.data).toString())){returnfalse;}queue.push(curr.right);}}returntrue;}// Main function to check if two trees are isomorphicfunctionisIsomorphic(root1,root2){constvisited=newMap();// Mark the root of the first tree as visitedvisited.set(newPair(root1.data,-1).toString(),true);constqueue=[root1];// Traverse the first tree and mark nodes as visitedwhile(queue.length>0){constcurr=queue.shift();if(curr.left){visited.set(newPair(curr.left.data,curr.data).toString(),true);queue.push(curr.left);}if(curr.right){visited.set(newPair(curr.right.data,curr.data).toString(),true);queue.push(curr.right);}}// Use the helper function to check the second treereturncheckTree(root2,visited);}// Representation of input binary tree 1// 1// / \// 2 3// / \ /// 4 5 6// / \// 7 8letroot1=newNode(1);root1.left=newNode(2);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(5);root1.right.left=newNode(6);root1.left.right.left=newNode(7);root1.left.right.right=newNode(8);// Representation of input binary tree 2// 1// / \// 3 2// \ / \// 6 4 5// / \// 8 7letroot2=newNode(1);root2.left=newNode(3);root2.right=newNode(2);root2.left.right=newNode(6);root2.right.left=newNode(4);root2.right.right=newNode(5);root2.right.right.left=newNode(8);root2.right.right.right=newNode(7);console.log(isIsomorphic(root1,root2)?"True":"False");