Foldable Binary Trees
Last Updated :
13 Jan, 2023
Given a binary tree, find out if the tree can be folded or not. A tree can be folded if the left and right subtrees of the tree are structure-wise mirror images of each other. An empty tree is considered foldable.
Examples:
Input:
10
/ \
7 15
\ /
9 11
Output: Can be folded
Input:
10
/ \
7 15
/ /
5 11
Output: Cannot be folded
Foldable Binary Trees by Changing Left Subtree to its Mirror:
The idea is to change the left subtree to its mirror then check that left subtree with its right subtree.
Follow the steps below to solve the problem:
- If tree is empty, then return true.
- Convert the left subtree to its mirror image
- Check if the structure of left subtree and right subtree is same and store the result.
- res = isStructSame(root->left, root->right). isStructSame() recursively compares structures of two subtrees and returns true if structures are same
- Revert the changes made in step (2) to get the original tree.
- Return result res stored in step 3.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
class node {
public :
int data;
node* left;
node* right;
};
void mirror(node* node);
bool isStructSame(node* a, node* b);
bool isFoldable(node* root)
{
bool res;
if (root == NULL)
return true ;
mirror(root->left);
res = isStructSame(root->left, root->right);
mirror(root->left);
return res;
}
bool isStructSame(node* a, node* b)
{
if (a == NULL && b == NULL) {
return true ;
}
if (a != NULL && b != NULL
&& isStructSame(a->left, b->left)
&& isStructSame(a->right, b->right)) {
return true ;
}
return false ;
}
void mirror(node* Node)
{
if (Node == NULL)
return ;
else {
node* temp;
mirror(Node->left);
mirror(Node->right);
temp = Node->left;
Node->left = Node->right;
Node->right = temp;
}
}
node* newNode( int data)
{
node* Node = new node();
Node->data = data;
Node->left = NULL;
Node->right = NULL;
return (Node);
}
int main( void )
{
node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->right = newNode(4);
root->right->left = newNode(5);
if (isFoldable(root) == 1) {
cout << "tree is foldable" ;
}
else {
cout << "\ntree is not foldable" ;
}
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
#define bool int
#define true 1
#define false 0
struct node {
int data;
struct node* left;
struct node* right;
};
void mirror( struct node* node);
bool isStructSame( struct node* a, struct node* b);
bool isFoldable( struct node* root)
{
bool res;
if (root == NULL)
return true ;
mirror(root->left);
res = isStructSame(root->left, root->right);
mirror(root->left);
return res;
}
bool isStructSame( struct node* a, struct node* b)
{
if (a == NULL && b == NULL) {
return true ;
}
if (a != NULL && b != NULL
&& isStructSame(a->left, b->left)
&& isStructSame(a->right, b->right)) {
return true ;
}
return false ;
}
void mirror( struct node* node)
{
if (node == NULL)
return ;
else {
struct node* temp;
mirror(node->left);
mirror(node->right);
temp = node->left;
node->left = node->right;
node->right = temp;
}
}
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 main( void )
{
struct node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->right->left = newNode(4);
root->left->right = newNode(5);
if (isFoldable(root) == 1) {
printf ( "\n tree is foldable" );
}
else {
printf ( "\n tree is not foldable" );
}
getchar ();
return 0;
}
|
Java
class Node {
int data;
Node left, right;
Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree {
Node root;
boolean isFoldable(Node node)
{
boolean res;
if (node == null )
return true ;
mirror(node.left);
res = isStructSame(node.left, node.right);
mirror(node.left);
return res;
}
boolean isStructSame(Node a, Node b)
{
if (a == null && b == null )
return true ;
if (a != null && b != null
&& isStructSame(a.left, b.left)
&& isStructSame(a.right, b.right))
return true ;
return false ;
}
void mirror(Node node)
{
if (node == null )
return ;
else {
Node temp;
mirror(node.left);
mirror(node.right);
temp = node.left;
node.left = node.right;
node.right = temp;
}
}
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( 3 );
tree.root.right.left = new Node( 4 );
tree.root.left.right = new Node( 5 );
if (tree.isFoldable(tree.root))
System.out.println( "tree is foldable" );
else
System.out.println( "Tree is not foldable" );
}
}
|
Python3
class newNode:
def __init__( self , d):
self .data = d
self .left = None
self .right = None
def isFoldable(node):
if node = = None :
return true
mirror(node.left)
res = isStructSame(node.left, node.right)
mirror(node.left)
return res
def isStructSame(a, b):
if a = = None and b = = None :
return True
if a ! = None and b ! = None and isStructSame(a.left, b.left) and isStructSame(a.right, b.right):
return True
return False
def mirror(node):
if node = = None :
return
else :
mirror(node.left)
mirror(node.right)
temp = node.left
node.left = node.right
node.right = temp
if __name__ = = '__main__' :
root = newNode( 1 )
root.left = newNode( 2 )
root.right = newNode( 3 )
root.right.left = newNode( 4 )
root.left.right = newNode( 5 )
if isFoldable(root):
print ( "tree is foldable" )
else :
print ( "Tree is not foldable" )
|
C#
using System;
class Node {
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree {
Node root;
Boolean isFoldable(Node node)
{
Boolean res;
if (node == null )
return true ;
mirror(node.left);
res = isStructSame(node.left, node.right);
mirror(node.left);
return res;
}
Boolean isStructSame(Node a, Node b)
{
if (a == null && b == null )
return true ;
if (a != null && b != null
&& isStructSame(a.left, b.left)
&& isStructSame(a.right, b.right))
return true ;
return false ;
}
void mirror(Node node)
{
if (node == null )
return ;
else {
Node temp;
mirror(node.left);
mirror(node.right);
temp = node.left;
node.left = node.right;
node.right = temp;
}
}
static public void Main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.right.left = new Node(4);
tree.root.left.right = new Node(5);
if (tree.isFoldable(tree.root))
Console.WriteLine( "tree is foldable" );
else
Console.WriteLine( "Tree is not foldable" );
}
}
|
Javascript
<script>
class Node
{
constructor(item)
{
this .data=item;
this .left= this .right= null ;
}
}
function isFoldable(node)
{
let res;
if (node == null )
return true ;
mirror(node.left);
res = isStructSame(node.left, node.right);
mirror(node.left);
return res;
}
function isStructSame(a,b)
{
if (a == null && b == null )
return true ;
if (a != null && b != null
&& isStructSame(a.left, b.left)
&& isStructSame(a.right, b.right))
return true ;
return false ;
}
function mirror(node)
{
if (node == null )
return ;
else {
let temp;
mirror(node.left);
mirror(node.right);
temp = node.left;
node.left = node.right;
node.right = temp;
}
}
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.right.left = new Node(4);
root.left.right = new Node(5);
if (isFoldable(root))
document.write( "tree is foldable" );
else
document.write( "Tree is not foldable" );
</script>
|
Time complexity: O(N), Visiting all the nodes of the tree of size N.
Auxiliary Space: O(N), If stack space is considered else O(1)
Thanks to ajaym for suggesting this approach.
Foldable Binary Trees by Checking if Left and Right subtrees are Mirror:
The idea is to check the left and right subtree whether they are mirror or not.
Follow the steps below to solve the problem:
- If tree is empty then return true.
- Else check if left and right subtrees are structure wise mirrors of each other. Use utility function IsFoldableUtil(root->left, root->right) for this.
- Checks if n1 and n2 are mirror of each other.
- If both trees are empty then return true.
- If one of them is empty and other is not then return false.
- Return true if following conditions are met
- n1->left is mirror of n2->right
- n1->right is mirror of n2->left
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
class node {
public :
int data;
node* left;
node* right;
};
bool IsFoldableUtil(node* n1, node* n2);
bool IsFoldable(node* root)
{
if (root == NULL) {
return true ;
}
return IsFoldableUtil(root->left, root->right);
}
bool IsFoldableUtil(node* n1, node* n2)
{
if (n1 == NULL && n2 == NULL) {
return true ;
}
if (n1 == NULL || n2 == NULL) {
return false ;
}
return IsFoldableUtil(n1->left, n2->right)
&& IsFoldableUtil(n1->right, n2->left);
}
node* newNode( int data)
{
node* Node = new node();
Node->data = data;
Node->left = NULL;
Node->right = NULL;
return (Node);
}
int main( void )
{
node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->right = newNode(4);
root->right->left = newNode(5);
if (IsFoldable(root) == true ) {
cout << "tree is foldable" ;
}
else {
cout << "tree is not foldable" ;
}
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
#define bool int
#define true 1
#define false 0
struct node {
int data;
struct node* left;
struct node* right;
};
bool IsFoldableUtil( struct node* n1, struct node* n2);
bool IsFoldable( struct node* root)
{
if (root == NULL) {
return true ;
}
return IsFoldableUtil(root->left, root->right);
}
bool IsFoldableUtil( struct node* n1, struct node* n2)
{
if (n1 == NULL && n2 == NULL) {
return true ;
}
if (n1 == NULL || n2 == NULL) {
return false ;
}
return IsFoldableUtil(n1->left, n2->right)
&& IsFoldableUtil(n1->right, n2->left);
}
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 main( void )
{
struct node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->right = newNode(4);
root->right->left = newNode(5);
if (IsFoldable(root) == true ) {
printf ( "\n tree is foldable" );
}
else {
printf ( "\n tree is not foldable" );
}
getchar ();
return 0;
}
|
Java
class Node {
int data;
Node left, right;
Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree {
Node root;
boolean IsFoldable(Node node)
{
if (node == null )
return true ;
return IsFoldableUtil(node.left, node.right);
}
boolean IsFoldableUtil(Node n1, Node n2)
{
if (n1 == null && n2 == null )
return true ;
if (n1 == null || n2 == null )
return false ;
return IsFoldableUtil(n1.left, n2.right)
&& IsFoldableUtil(n1.right, n2.left);
}
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( 3 );
tree.root.right.left = new Node( 4 );
tree.root.left.right = new Node( 5 );
if (tree.IsFoldable(tree.root))
System.out.println( "tree is foldable" );
else
System.out.println( "Tree is not foldable" );
}
}
|
Python3
class newNode:
def __init__( self , data):
self .data = data
self .left = self .right = None
def IsFoldable(root):
if (root = = None ):
return True
return IsFoldableUtil(root.left, root.right)
def IsFoldableUtil(n1, n2):
if n1 = = None and n2 = = None :
return True
if n1 = = None or n2 = = None :
return False
d1 = IsFoldableUtil(n1.left, n2.right)
d2 = IsFoldableUtil(n1.right, n2.left)
return d1 and d2
if __name__ = = "__main__" :
root = newNode( 1 )
root.left = newNode( 2 )
root.right = newNode( 3 )
root.left.right = newNode( 4 )
root.right.left = newNode( 5 )
if IsFoldable(root):
print ( "tree is foldable" )
else :
print ( "tree is not foldable" )
|
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 {
Node root;
bool IsFoldable(Node node)
{
if (node == null )
return true ;
return IsFoldableUtil(node.left, node.right);
}
bool IsFoldableUtil(Node n1, Node n2)
{
if (n1 == null && n2 == null )
return true ;
if (n1 == null || n2 == null )
return false ;
return IsFoldableUtil(n1.left, n2.right)
&& IsFoldableUtil(n1.right, n2.left);
}
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(3);
tree.root.right.left = new Node(4);
tree.root.left.right = new Node(5);
if (tree.IsFoldable(tree.root))
Console.WriteLine( "tree is foldable" );
else
Console.WriteLine( "Tree is not foldable" );
}
}
|
Javascript
<script>
class Node
{
constructor(data) {
this .left = null ;
this .right = null ;
this .data = data;
}
}
let root;
function IsFoldable(node)
{
if (node == null )
return true ;
return IsFoldableUtil(node.left, node.right);
}
function IsFoldableUtil(n1, n2)
{
if (n1 == null && n2 == null )
return true ;
if (n1 == null || n2 == null )
return false ;
return IsFoldableUtil(n1.left, n2.right)
&& IsFoldableUtil(n1.right, n2.left);
}
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.right.left = new Node(4);
root.left.right = new Node(5);
if (IsFoldable(root))
document.write( "tree is foldable" );
else
document.write( "Tree is not foldable" );
</script>
|
Time Complexity: O(N), Visiting every node of the tree of size N.
Auxiliary Space: O(N), If stack space is considered
The idea is to use Queue for traversing the tree and using the BFS approach.
Follow the steps below to solve the problem:
- The left child of the left subtree = the right child of the right subtree. Both of them should be not null.
- The right child of the left subtree = left child of the right subtree. Both of them should be null or not null.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Node
{
public :
int key;
Node *left;
Node *right;
Node( int key)
{
this ->key = key;
left = right = NULL;
}
};
class FoldableTrees
{
public :
Node *root = NULL;
bool isFoldable()
{
queue<Node *> q;
if (root != NULL)
{
q.push(root->left);
q.push(root->right);
}
while (!q.empty())
{
Node *p = q.front();
q.pop();
Node *r = q.front();
q.pop();
if (p == NULL && r == NULL)
continue ;
if ((p == NULL && r != NULL) || (p != NULL && r == NULL))
return false ;
q.push(p->left);
q.push(r->right);
q.push(p->right);
q.push(r->left);
}
return true ;
}
};
int main()
{
FoldableTrees tree = FoldableTrees();
tree.root = new Node(1);
tree.root->left = new Node(2);
tree.root->right = new Node(3);
tree.root->right->left = new Node(4);
tree.root->left->right = new Node(5);
if (tree.isFoldable())
cout << "tree is foldable" << endl;
else
cout << "tree is not foldable" << endl;
}
|
Java
import java.util.LinkedList;
import java.util.Queue;
public class FoldableTrees {
Node root = null ;
class Node {
int key;
Node left;
Node right;
Node( int key)
{
this .key = key;
left = right = null ;
}
}
boolean isFoldable()
{
Queue<Node> q = new LinkedList<>();
if (root != null ) {
q.add(root.left);
q.add(root.right);
}
while (!q.isEmpty()) {
Node p = q.remove();
Node r = q.remove();
if (p == null && r == null )
continue ;
if ((p == null && r != null )
|| (p != null && r == null ))
return false ;
q.add(p.left);
q.add(r.right);
q.add(p.right);
q.add(r.left);
}
return true ;
}
public static void main(String args[])
{
FoldableTrees tree = new FoldableTrees();
tree.root = tree. new Node( 1 );
tree.root.left = tree. new Node( 2 );
tree.root.right = tree. new Node( 3 );
tree.root.right.left = tree. new Node( 4 );
tree.root.left.right = tree. new Node( 5 );
if (tree.isFoldable())
System.out.println( "tree is foldable" );
else
System.out.println( "tree is not foldable" );
}
}
|
Python3
class Node:
def __init__( self , key):
self .key = key
self .left = None
self .right = None
def isFoldable(root):
q = []
if root ! = None :
q.append(root.left)
q.append(root.right)
while ( len (q) ! = 0 ):
p = q.pop( 0 )
r = q.pop( 0 )
if (p = = None and r = = None ):
continue
if ((p = = None and r ! = None ) or (p ! = None and r = = None )):
return False
q.append(p.left)
q.append(r.right)
q.append(p.right)
q.append(r.left)
return True
root = Node( 1 )
root.left = Node( 2 )
root.right = Node( 3 )
root.right.left = Node( 4 )
root.left.right = Node( 5 )
if isFoldable(root):
print ( "tree is foldable" )
else :
print ( "tree is not foldable" )
|
C#
using System;
using System.Collections.Generic;
public class Node {
public int key;
public Node left, right;
public Node( int key)
{
this .key = key;
this .left = this .right = null ;
}
}
public class FoldableTrees {
Node root = null ;
bool isFoldable()
{
Queue<Node> q = new Queue<Node>();
if (root != null ) {
q.Enqueue(root.left);
q.Enqueue(root.right);
}
while (q.Count != 0) {
Node p = q.Dequeue();
Node r = q.Dequeue();
if (p == null && r == null )
continue ;
if ((p == null && r != null )
|| (p != null && r == null ))
return false ;
q.Enqueue(p.left);
q.Enqueue(r.right);
q.Enqueue(p.right);
q.Enqueue(r.left);
}
return true ;
}
static public void Main()
{
FoldableTrees tree = new FoldableTrees();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.right.left = new Node(4);
tree.root.left.right = new Node(5);
if (tree.isFoldable())
Console.WriteLine( "tree is foldable" );
else
Console.WriteLine( "tree is not foldable" );
}
}
|
Javascript
<script>
let root = null ;
class Node
{
constructor(key)
{
this .key=key;
this .left= this .right= null ;
}
}
function isFoldable()
{
let q = [];
if (root != null ) {
q.push(root.left);
q.push(root.right);
}
while (q.length!=0) {
let p = q.shift();
let r = q.shift();
if (p == null && r == null )
continue ;
if ((p == null && r != null ) || (p != null && r == null ))
return false ;
q.push(p.left);
q.push(r.right);
q.push(p.right);
q.push(r.left);
}
return true ;
}
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.right.left = new Node(4);
root.left.right = new Node(5);
if (isFoldable())
document.write( "Tree is foldable" );
else
document.write( "Tree is not foldable" );
</script>
|
Time complexity: O(N), Visiting all the nodes of the tree of size N.
Auxiliary Space: O(N), Using queue for storing nodes
Please write comments if you find the above code/algorithm incorrect, or find other ways to solve the same problem.
Please Login to comment...