Given two Binary Trees, write a function that returns true if two trees are mirror of each other, else false. For example, the function should return true for following input trees.

This problem is different from the problem discussed here.
For two trees ‘a’ and ‘b’ to be mirror images, the following three conditions must be true:
- Their root node’s key must be same
- Left subtree of root of ‘a’ and right subtree root of ‘b’ are mirror.
- Right subtree of ‘a’ and left subtree of ‘b’ are mirror.
Below is implementation of above idea.
C++
#include<bits/stdc++.h>
using namespace std;
struct Node
{
int data;
Node* left, *right;
};
bool areMirror(Node* a, Node* b)
{
if (a==NULL && b==NULL)
return true ;
if (a==NULL || b == NULL)
return false ;
return a->data == b->data &&
areMirror(a->left, b->right) &&
areMirror(a->right, b->left);
}
Node* newNode( int data)
{
Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return (node);
}
int main()
{
Node *a = newNode(1);
Node *b = newNode(1);
a->left = newNode(2);
a->right = newNode(3);
a->left->left = newNode(4);
a->left->right = newNode(5);
b->left = newNode(3);
b->right = newNode(2);
b->right->left = newNode(5);
b->right->right = newNode(4);
areMirror(a, b)? cout << "Yes" : cout << "No" ;
return 0;
}
|
Java
class Node
{
int data;
Node left, right;
public Node( int data)
{
this .data = data;
left = right = null ;
}
}
class BinaryTree
{
Node a, b;
boolean areMirror(Node a, Node b)
{
if (a == null && b == null )
return true ;
if (a == null || b == null )
return false ;
return a.data == b.data
&& areMirror(a.left, b.right)
&& areMirror(a.right, b.left);
}
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
Node a = new Node( 1 );
Node b = new Node( 1 );
a.left = new Node( 2 );
a.right = new Node( 3 );
a.left.left = new Node( 4 );
a.left.right = new Node( 5 );
b.left = new Node( 3 );
b.right = new Node( 2 );
b.right.left = new Node( 5 );
b.right.right = new Node( 4 );
if (tree.areMirror(a, b) == true )
System.out.println( "Yes" );
else
System.out.println( "No" );
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def areMirror(a, b):
if a is None and b is None :
return True
if a is None or b is None :
return False
return (a.data = = b.data and
areMirror(a.left, b.right) and
areMirror(a.right , b.left))
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( 3 )
root2.right = Node( 2 )
root2.right.left = Node( 5 )
root2.right.right = Node( 4 )
if areMirror(root1, root2):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
public class Node
{
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
left = right = null ;
}
}
public class BinaryTree
{
public Node a, b;
public virtual bool areMirror(Node a, Node b)
{
if (a == null && b == null )
{
return true ;
}
if (a == null || b == null )
{
return false ;
}
return a.data == b.data && areMirror(a.left, b.right)
&& areMirror(a.right, b.left);
}
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
Node a = new Node(1);
Node b = new Node(1);
a.left = new Node(2);
a.right = new Node(3);
a.left.left = new Node(4);
a.left.right = new Node(5);
b.left = new Node(3);
b.right = new Node(2);
b.right.left = new Node(5);
b.right.right = new Node(4);
if (tree.areMirror(a, b) == true )
{
Console.WriteLine( "Yes" );
}
else
{
Console.WriteLine( "No" );
}
}
}
|
Javascript
<script>
class Node {
Node(data) {
this .data = data;
this .left = this .right = null ;
}
}
var a, b;
function areMirror( a, b) {
if (a == null && b == null )
return true ;
if (a == null || b == null )
return false ;
return a.data == b.data && areMirror(a.left, b.right) && areMirror(a.right, b.left);
}
a = new Node(1);
b = new Node(1);
left = new Node(2);
right = new Node(3);
left.left = new Node(4);
left.right = new Node(5);
left = new Node(3);
right = new Node(2);
right.left = new Node(5);
right.right = new Node(4);
if (areMirror(a, b) == true )
document.write( "Yes" );
else
document.write( "No" );
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(h) where h is height of binary tree
Approach 2: Iterative Solution
Another approach to check if two trees are mirrors of each other is to use an iterative algorithm that uses a stack to keep track of the nodes being traversed. This algorithm is similar to the iterative algorithm for checking if a tree is symmetric, but with a slight modification to check for mirror symmetry.
This solution uses two stacks to iterate over the two trees in a synchronized way. It pops a node from both stacks, checks if their data is equal, and then pushes their left and right children onto the stacks in the opposite order. The algorithm terminates early if at any point the nodes being compared have unequal data or unequal numbers of children.
Here is the implementation for the iterative solution:
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;
}
};
bool isMirrorIterative(Node* root1, Node* root2)
{
if (root1 == NULL && root2 == NULL)
return true ;
if (root1 == NULL || root2 == NULL)
return false ;
stack<Node*> s1, s2;
s1.push(root1);
s2.push(root2);
while (!s1.empty() && !s2.empty())
{
Node* curr1 = s1.top();
s1.pop();
Node* curr2 = s2.top();
s2.pop();
if (curr1->data != curr2->data)
return false ;
if (curr1->left != NULL && curr2->right != NULL)
{
s1.push(curr1->left);
s2.push(curr2->right);
}
else if (curr1->left != NULL || curr2->right != NULL)
return false ;
if (curr1->right != NULL && curr2->left != NULL)
{
s1.push(curr1->right);
s2.push(curr2->left);
}
else if (curr1->right != NULL || curr2->left != NULL)
return false ;
}
if (!s1.empty() || !s2.empty())
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(3);
root2->right = new Node(2);
root2->right->left = new Node(5);
root2->right->right = new Node(4);
if (isMirrorIterative(root1, root2))
cout << "Yes" << endl;
else
cout << "No" << endl;
return 0;
}
|
Java
import java.util.*;
class Node {
int data;
Node left;
Node right;
Node( int d) {
this .data = d;
this .left = null ;
this .right = null ;
}
}
class Main {
static boolean isMirrorIterative(Node root1, Node root2) {
if (root1 == null && root2 == null )
return true ;
if (root1 == null || root2 == null )
return false ;
Stack<Node> s1 = new Stack<>();
Stack<Node> s2 = new Stack<>();
s1.push(root1);
s2.push(root2);
while (!s1.empty() && !s2.empty()) {
Node curr1 = s1.pop();
Node curr2 = s2.pop();
if (curr1.data != curr2.data)
return false ;
if (curr1.left != null && curr2.right != null ) {
s1.push(curr1.left);
s2.push(curr2.right);
} else if (curr1.left != null || curr2.right != null )
return false ;
if (curr1.right != null && curr2.left != null ) {
s1.push(curr1.right);
s2.push(curr2.left);
} else if (curr1.right != null || curr2.left != null )
return false ;
}
if (!s1.empty() || !s2.empty())
return false ;
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( 3 );
root2.right = new Node( 2 );
root2.right.left = new Node( 5 );
root2.right.right = new Node( 4 );
if (isMirrorIterative(root1, root2))
System.out.println( "Yes" );
else
System.out.println( "No" );
}
}
|
Python3
class Node:
def __init__( self , d):
self .data = d
self .left = None
self .right = None
def isMirrorIterative(root1, root2):
if root1 is None and root2 is None :
return True
if root1 is None or root2 is None :
return False
stack1 = []
stack2 = []
stack1.append(root1)
stack2.append(root2)
while len (stack1) > 0 and len (stack2) > 0 :
curr1 = stack1.pop()
curr2 = stack2.pop()
if curr1.data ! = curr2.data:
return False
if curr1.left is not None and curr2.right is not None :
stack1.append(curr1.left)
stack2.append(curr2.right)
elif curr1.left is not None or curr2.right is not None :
return False
if curr1.right is not None and curr2.left is not None :
stack1.append(curr1.right)
stack2.append(curr2.left)
elif curr1.right is not None or curr2.left is not None :
return False
if len (stack1) > 0 or len (stack2) > 0 :
return False
return True
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( 3 )
root2.right = Node( 2 )
root2.right.left = Node( 5 )
root2.right.right = Node( 4 )
if isMirrorIterative(root1, root2):
print ( "Yes" )
else :
print ( "No" )
|
Javascript
class Node {
constructor(d) {
this .data = d;
this .left = null ;
this .right = null ;
}
}
function isMirrorIterative(root1, root2) {
if (root1 === null && root2 === null )
return true ;
if (root1 === null || root2 === null )
return false ;
const stack1 = [];
const stack2 = [];
stack1.push(root1);
stack2.push(root2);
while (stack1.length > 0 && stack2.length > 0) {
const curr1 = stack1.pop();
const curr2 = stack2.pop();
if (curr1.data !== curr2.data)
return false ;
if (curr1.left !== null && curr2.right !== null ) {
stack1.push(curr1.left);
stack2.push(curr2.right);
} else if (curr1.left !== null || curr2.right !== null )
return false ;
if (curr1.right !== null && curr2.left !== null ) {
stack1.push(curr1.right);
stack2.push(curr2.left);
} else if (curr1.right !== null || curr2.left !== null )
return false ;
}
if (stack1.length > 0 || stack2.length > 0)
return false ;
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(3);
root2.right = new Node(2);
root2.right.left = new Node(5);
root2.right.right = new Node(4);
if (isMirrorIterative(root1, root2))
console.log( "Yes" );
else
console.log( "No" );
|
Time Complexity: O(n)
Auxiliary Space: O(h) where h is height of binary tree
Iterative method to check if two trees are mirror of each other
This article is contributed by Ashish Gupta. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.