Given a binary tree, check whether it is a mirror of itself.
For example, this binary tree is symmetric:
1
/ \
2 2
/ \ / \
3 4 4 3
But the following is not:
1
/ \
2 2
\ \
3 3
The idea is to write a recursive function isMirror() that takes two trees as an argument and returns true if trees are the mirror and false if trees are not mirrored. The isMirror() function recursively checks two roots and subtrees under the root.
Below is the implementation of the above algorithm.
C++14
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
struct Node *left, *right;
};
Node* newNode( int key)
{
Node* temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
bool isMirror( struct Node* root1, struct Node* root2)
{
if (root1 == NULL && root2 == NULL)
return true ;
if (root1 && root2 && root1->key == root2->key)
return isMirror(root1->left, root2->right)
&& isMirror(root1->right, root2->left);
return false ;
}
bool isSymmetric( struct Node* root)
{
return isMirror(root, root);
}
int main()
{
Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(2);
root->left->left = newNode(3);
root->left->right = newNode(4);
root->right->left = newNode(4);
root->right->right = newNode(3);
if (isSymmetric(root))
cout << "Symmetric" ;
else
cout << "Not symmetric" ;
return 0;
}
|
C
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int key;
struct Node *left, *right;
} Node;
Node* newNode( int key)
{
Node* temp = (Node *) malloc ( sizeof (Node));
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
bool isMirror(Node* root1, Node* root2)
{
if (root1 == NULL && root2 == NULL)
return true ;
if (root1 && root2 && root1->key == root2->key)
return isMirror(root1->left, root2->right)
&& isMirror(root1->right, root2->left);
return false ;
}
bool isSymmetric(Node* root)
{
return isMirror(root, root);
}
int main()
{
Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(2);
root->left->left = newNode(3);
root->left->right = newNode(4);
root->right->left = newNode(4);
root->right->right = newNode(3);
if (isSymmetric(root))
printf ( "Symmetric" );
else
printf ( "Not symmetric" );
return 0;
}
|
Java
class Node {
int key;
Node left, right;
Node( int item)
{
key = item;
left = right = null ;
}
}
class BinaryTree {
Node root;
boolean isMirror(Node node1, Node node2)
{
if (node1 == null && node2 == null )
return true ;
if (node1 != null && node2 != null
&& node1.key == node2.key)
return (isMirror(node1.left, node2.right)
&& isMirror(node1.right, node2.left));
return false ;
}
boolean isSymmetric()
{
return isMirror(root, root);
}
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node( 1 );
tree.root.left = new Node( 2 );
tree.root.right = new Node( 2 );
tree.root.left.left = new Node( 3 );
tree.root.left.right = new Node( 4 );
tree.root.right.left = new Node( 4 );
tree.root.right.right = new Node( 3 );
boolean output = tree.isSymmetric();
if (output == true )
System.out.println( "Symmetric" );
else
System.out.println( "Not symmetric" );
}
}
|
Python3
class Node:
def __init__( self , key):
self .key = key
self .left = None
self .right = None
def isMirror(root1, root2):
if root1 is None and root2 is None :
return True
if (root1 is not None and root2 is not None ):
if root1.key = = root2.key:
return (isMirror(root1.left, root2.right) and
isMirror(root1.right, root2.left))
return False
def isSymmetric(root):
return isMirror(root, root)
root = Node( 1 )
root.left = Node( 2 )
root.right = Node( 2 )
root.left.left = Node( 3 )
root.left.right = Node( 4 )
root.right.left = Node( 4 )
root.right.right = Node( 3 )
print ( "Symmetric" if isSymmetric(root) = = True else "Not symmetric" )
|
C#
using System;
class Node {
public int key;
public Node left, right;
public Node( int item)
{
key = item;
left = right = null ;
}
}
class GFG {
Node root;
Boolean isMirror(Node node1, Node node2)
{
if (node1 == null && node2 == null )
return true ;
if (node1 != null && node2 != null
&& node1.key == node2.key)
return (isMirror(node1.left, node2.right)
&& isMirror(node1.right, node2.left));
return false ;
}
Boolean isSymmetric()
{
return isMirror(root, root);
}
static public void Main(String[] args)
{
GFG tree = new GFG();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(2);
tree.root.left.left = new Node(3);
tree.root.left.right = new Node(4);
tree.root.right.left = new Node(4);
tree.root.right.right = new Node(3);
Boolean output = tree.isSymmetric();
if (output == true )
Console.WriteLine( "Symmetric" );
else
Console.WriteLine( "Not symmetric" );
}
}
|
Javascript
<script>
class Node {
constructor(item)
{
this .key = item;
this .left = null ;
this .right = null ;
}
}
var root = null ;
function isMirror(node1, node2)
{
if (node1 == null && node2 == null )
return true ;
if (node1 != null && node2 != null
&& node1.key == node2.key)
return (isMirror(node1.left, node2.right)
&& isMirror(node1.right, node2.left));
return false ;
}
function isSymmetric()
{
return isMirror(root, root);
}
root = new Node(1);
root.left = new Node(2);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(4);
root.right.left = new Node(4);
root.right.right = new Node(3);
var output = isSymmetric();
if (output == true )
document.write( "Symmetric" );
else
document.write( "Not symmetric" );
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(h) where h is the maximum height of the tree
Iterative Approach:
Algorithm for checking whether a binary tree is a mirror of itself using an iterative approach and a stack:
- Create a stack and push the root node onto it twice.
- While the stack is not empty, repeat the following steps:
a. Pop two nodes from the stack, say node1 and node2.
b. If both node1 and node2 are null, continue to the next iteration.
c. If one of the nodes is null and the other is not, return false as it is not a mirror.
d. If both nodes are not null, compare their values. If they are not equal, return false.
e. Push the left child of node1 and the right child of node2 onto the stack.
f. Push the right child of node1 and the left child of node2 onto the stack.
- If the loop completes successfully without returning false, return true as it is a mirror.
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
struct Node *left, *right;
};
Node* newNode( int key)
{
Node* temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
bool isSymmetric(Node* root){
if (root == NULL) {
return true ;
}
stack<Node*> stack;
stack.push(root->left);
stack.push(root->right);
while (!stack.empty()) {
Node* node1 = stack.top();
stack.pop();
Node* node2 = stack.top();
stack.pop();
if (node1 == NULL && node2 == NULL) {
continue ;
}
if (node1 == NULL || node2 == NULL) {
return false ;
}
if (node1->key != node2->key) {
return false ;
}
stack.push(node1->left);
stack.push(node2->right);
stack.push(node1->right);
stack.push(node2->left);
}
return true ;
}
int main()
{
Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(2);
root->left->left = newNode(3);
root->left->right = newNode(4);
root->right->left = newNode(4);
root->right->right = newNode(3);
if (isSymmetric(root))
cout << "Symmetric" ;
else
cout << "Not symmetric" ;
return 0;
}
|
Java
import java.util.*;
class Node {
int key;
Node left, right;
Node( int item)
{
key = item;
left = right = null ;
}
}
public class GFG
{
static boolean isSymmetric(Node root)
{
if (root == null ) {
return true ;
}
Stack<Node> stack = new Stack<>();
stack.push(root.left);
stack.push(root.right);
while (!stack.empty()) {
Node node1 = stack.pop();
Node node2 = stack.pop();
if (node1 == null && node2 == null ) {
continue ;
}
if (node1 == null || node2 == null ) {
return false ;
}
if (node1.key != node2.key) {
return false ;
}
stack.push(node1.left);
stack.push(node2.right);
stack.push(node1.right);
stack.push(node2.left);
}
return true ;
}
public static void main(String[] args)
{
Node root = new Node( 1 );
root.left = new Node( 2 );
root.right = new Node( 2 );
root.left.left = new Node( 3 );
root.left.right = new Node( 4 );
root.right.left = new Node( 4 );
root.right.right = new Node( 3 );
if (isSymmetric(root))
System.out.println( "Symmetric" );
else
System.out.println( "Not symmetric" );
}
}
|
Python3
class Node:
def __init__( self , key):
self .key = key
self .left = None
self .right = None
def isSymmetric(root):
if not root:
return True
stack = []
stack.append(root.left)
stack.append(root.right)
while stack:
node1 = stack.pop()
node2 = stack.pop()
if not node1 and not node2:
continue
if not node1 or not node2:
return False
if node1.key ! = node2.key:
return False
stack.append(node1.left)
stack.append(node2.right)
stack.append(node1.right)
stack.append(node2.left)
return True
root = Node( 1 )
root.left = Node( 2 )
root.right = Node( 2 )
root.left.left = Node( 3 )
root.left.right = Node( 4 )
root.right.left = Node( 4 )
root.right.right = Node( 3 )
if isSymmetric(root):
print ( "Symmetric" )
else :
print ( "Not symmetric" )
|
C#
using System;
using System.Collections;
public class Node
{
public int key;
public Node left, right;
public Node( int item)
{
key = item;
left = right = null ;
}
}
public class GFG
{
static bool isSymmetric(Node root)
{
if (root == null )
{
return true ;
}
Stack stack = new Stack();
stack.Push(root.left);
stack.Push(root.right);
while (stack.Count != 0)
{
Node node1 = (Node)stack.Pop();
Node node2 = (Node)stack.Pop();
if (node1 == null && node2 == null )
{
continue ;
}
if (node1 == null || node2 == null )
{
return false ;
}
if (node1.key != node2.key)
{
return false ;
}
stack.Push(node1.left);
stack.Push(node2.right);
stack.Push(node1.right);
stack.Push(node2.left);
}
return true ;
}
public static void Main( string [] args)
{
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(4);
root.right.left = new Node(4);
root.right.right = new Node(3);
if (isSymmetric(root))
Console.WriteLine( "Symmetric" );
else
Console.WriteLine( "Not symmetric" );
}
}
|
Javascript
class Node {
constructor(item) {
this .key = item;
this .left = null ;
this .right = null ;
}
}
function isSymmetric(root) {
if (root === null ) {
return true ;
}
const stack = [];
stack.push(root.left);
stack.push(root.right);
while (stack.length > 0) {
const node1 = stack.pop();
const node2 = stack.pop();
if (node1 === null && node2 === null ) {
continue ;
}
if (node1 === null || node2 === null ) {
return false ;
}
if (node1.key !== node2.key) {
return false ;
}
stack.push(node1.left);
stack.push(node2.right);
stack.push(node1.right);
stack.push(node2.left);
}
return true ;
}
( function () {
const root = new Node(1);
root.left = new Node(2);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(4);
root.right.left = new Node(4);
root.right.right = new Node(3);
if (isSymmetric(root)) {
console.log( "Symmetric" );
} else {
console.log( "Not symmetric" );
}
})();
|
Time Complexity: O(n) where n is the number of nodes.
Space Complexity: O(h) where h is the height of the tree.
Iterative approach using a queue:
The basic idea is to check if the left and right subtrees of the root node are mirror images of each other. To do this, we perform a level-order traversal of the binary tree using a queue. We push the root node into the queue twice, initially. We dequeue two nodes at a time from the front of the queue and check if they are mirror images of each other.
Follow the steps to solve the problem:
- If the root node is NULL, return true as an empty binary tree is considered symmetric.
- Create a queue and push the root node twice into the queue.
- While the queue is not empty, dequeue two nodes at a time, one for the left subtree and one for the right subtree.
- If both the left and right nodes are NULL, continue to the next iteration as the subtrees are considered mirror images of each other.
- If either the left or right node is NULL, or their data is not equal, return false as they are not mirror images of each other.
- Push the left and right nodes of the left subtree into the queue, followed by the right and left nodes of the right subtree into the queue.
- If the queue becomes empty and we have not returned false till now, return true as the binary tree is symmetric.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* left;
struct Node* right;
Node( int val)
{
data = val;
left = NULL;
right = NULL;
}
};
bool isSymmetric( struct Node* root)
{
if (root == NULL) {
return true ;
}
queue<Node*> q;
q.push(root);
q.push(root);
while (!q.empty()) {
Node* leftNode = q.front();
q.pop();
Node* rightNode = q.front();
q.pop();
if (leftNode == NULL && rightNode == NULL) {
continue ;
}
if (leftNode == NULL || rightNode == NULL
|| leftNode->data != rightNode->data) {
return false ;
}
q.push(leftNode->left);
q.push(rightNode->right);
q.push(leftNode->right);
q.push(rightNode->left);
}
return true ;
}
int main()
{
struct Node* root = new Node(5);
root->left = new Node(1);
root->right = new Node(1);
root->left->left = new Node(2);
root->right->right = new Node(2);
if (isSymmetric(root)) {
cout << "The binary tree is symmetric\n" ;
}
else {
cout << "The binary tree is not symmetric\n" ;
}
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 SymmetricBinaryTree {
public static boolean isSymmetric(Node root) {
if (root == null ) {
return true ;
}
Queue<Node> q = new LinkedList<>();
q.add(root);
q.add(root);
while (!q.isEmpty()) {
Node leftNode = q.poll();
Node rightNode = q.poll();
if (leftNode == null && rightNode == null ) {
continue ;
}
if (leftNode == null || rightNode == null || leftNode.data != rightNode.data) {
return false ;
}
q.add(leftNode.left);
q.add(rightNode.right);
q.add(leftNode.right);
q.add(rightNode.left);
}
return true ;
}
public static void main(String[] args) {
Node root = new Node( 5 );
root.left = new Node( 1 );
root.right = new Node( 1 );
root.left.left = new Node( 2 );
root.right.right = new Node( 2 );
if (isSymmetric(root)) {
System.out.println( "The binary tree is symmetric" );
} else {
System.out.println( "The binary tree is not symmetric" );
}
}
}
|
Python3
from queue import Queue
class Node:
def __init__( self , val):
self .data = val
self .left = None
self .right = None
def isSymmetric(root):
if root is None :
return True
q = Queue()
q.put(root)
q.put(root)
while not q.empty():
leftNode = q.get()
rightNode = q.get()
if leftNode is None and rightNode is None :
continue
if leftNode is None or rightNode is None or leftNode.data ! = rightNode.data:
return False
q.put(leftNode.left)
q.put(rightNode.right)
q.put(leftNode.right)
q.put(rightNode.left)
return True
if __name__ = = '__main__' :
root = Node( 5 )
root.left = Node( 1 )
root.right = Node( 1 )
root.left.left = Node( 2 )
root.right.right = Node( 2 )
if isSymmetric(root):
print ( "The binary tree is symmetric" )
else :
print ( "The binary tree is not symmetric" )
|
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 BinaryTree
{
public static bool IsSymmetric(Node root)
{
if (root == null )
{
return true ;
}
Queue<Node> queue = new Queue<Node>();
queue.Enqueue(root);
queue.Enqueue(root);
while (queue.Count > 0)
{
Node leftNode = queue.Dequeue();
Node rightNode = queue.Dequeue();
if (leftNode == null && rightNode == null )
{
continue ;
}
if (leftNode == null || rightNode == null || leftNode.Data != rightNode.Data)
{
return false ;
}
queue.Enqueue(leftNode.Left);
queue.Enqueue(rightNode.Right);
queue.Enqueue(leftNode.Right);
queue.Enqueue(rightNode.Left);
}
return true ;
}
public static void Main( string [] args)
{
Node root = new Node(5);
root.Left = new Node(1);
root.Right = new Node(1);
root.Left.Left = new Node(2);
root.Right.Right = new Node(2);
if (IsSymmetric(root))
{
Console.WriteLine( "The binary tree is symmetric" );
}
else
{
Console.WriteLine( "The binary tree is not symmetric" );
}
}
}
|
Javascript
class Node {
constructor(val) {
this .data = val;
this .left = null ;
this .right = null ;
}
}
function isSymmetric(root) {
if (root === null ) {
return true ;
}
const q = [];
q.push(root);
q.push(root);
while (q.length > 0) {
const leftNode = q.shift();
const rightNode = q.shift();
if (leftNode === null && rightNode === null ) {
continue ;
}
if (leftNode === null || rightNode === null || leftNode.data !== rightNode.data) {
return false ;
}
q.push(leftNode.left);
q.push(rightNode.right);
q.push(leftNode.right);
q.push(rightNode.left);
}
return true ;
}
function main() {
const root = new Node(5);
root.left = new Node(1);
root.right = new Node(1);
root.left.left = new Node(2);
root.right.right = new Node(2);
if (isSymmetric(root)) {
console.log( "The binary tree is symmetric" );
} else {
console.log( "The binary tree is not symmetric" );
}
}
main();
|
Output
The binary tree is symmetric
Time Complexity: O(n),The time complexity of this approach is O(n), where n is the number of nodes in the binary tree.
This is because we visit each node of the binary tree once.
Space Complexity: O(n) , The space complexity of this approach is O(n), where n is the number of nodes in the binary tree.
This is because we store the nodes of the binary tree in a queue.
In the worst-case scenario, the queue can contain all the nodes of the binary tree at the last level, which is approximately n/2 nodes.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
09 Oct, 2023
Like Article
Save Article