Check if a Binary Tree is subtree of another Binary Tree
Last Updated : 6 Apr, 2026
Given two binary trees, a tree T (root1) with n nodes and a tree S (root2) with m nodes, check whether S is a subtree of T. A tree S is a subtree of T if it is formed by choosing any node in T and including all of its descendants. If S exactly matches any such subtree of T in both structure and node values, then it is considered a subtree.
Examples:
Input:
Output: true Explanation: root2 is the subtree of root1.
[Naive Approach] Preorder Traversal with Subtree Matching - O(n*m) Time and O(n+m) Space
Traverse the main tree (root1) in preorder. At each node, treat it as a potential root and check whether the subtree rooted at this node is identical to root2. The identical check is done by recursively comparing both trees for matching structure and node values. Return true if a match is found at any node, otherwise, continue the traversal.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};// Check if two trees are identicalboolareIdentical(Node*root1,Node*root2){// Both nodes are null → identicalif(root1==nullptr&&root2==nullptr)returntrue;// One is null => not identicalif(root1==nullptr||root2==nullptr)returnfalse;// Check current node and recurse on childrenreturn(root1->data==root2->data&&areIdentical(root1->left,root2->left)&&areIdentical(root1->right,root2->right));}boolisSubTree(Node*root1,Node*root2){// Empty subtree => always trueif(root2==nullptr)returntrue;// Main tree empty but subtree not => falseif(root1==nullptr)returnfalse;// Match found at current nodeif(areIdentical(root1,root2))returntrue;// Otherwise, search in left and rightreturnisSubTree(root1->left,root2)||isSubTree(root1->right,root2);}intmain(){// Construct Tree root1// 26// / \ // 10 3// / \ \ // 4 6 3// \ // 30Node*root1=newNode(26);root1->left=newNode(10);root1->right=newNode(3);root1->left->left=newNode(4);root1->left->right=newNode(6);root1->left->left->right=newNode(30);root1->right->right=newNode(3);// Construct Tree root2// 10// / \ // 4 6// \ // 30Node*root2=newNode(10);root2->left=newNode(4);root2->right=newNode(6);root2->left->right=newNode(30);cout<<(isSubTree(root1,root2)?"true":"false");return0;}
Java
classNode{intdata;Nodeleft;Noderight;Node(intvalue){data=value;left=right=null;}}classGFG{// Check if two trees are identicalstaticbooleanareIdentical(Noderoot1,Noderoot2){// Both nodes are null → identicalif(root1==null&&root2==null)returntrue;// One is null → not identicalif(root1==null||root2==null)returnfalse;// Check current node and recurse on childrenreturn(root1.data==root2.data&&areIdentical(root1.left,root2.left)&&areIdentical(root1.right,root2.right));}staticbooleanisSubTree(Noderoot1,Noderoot2){// Empty subtree → always trueif(root2==null)returntrue;// Main tree empty but subtree not → falseif(root1==null)returnfalse;// Match found at current nodeif(areIdentical(root1,root2))returntrue;// Otherwise, search in left and rightreturnisSubTree(root1.left,root2)||isSubTree(root1.right,root2);}publicstaticvoidmain(String[]args){// Construct Tree root1// 26// / \// 10 3// / \ \// 4 6 3// \// 30Noderoot1=newNode(26);root1.left=newNode(10);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(6);root1.left.left.right=newNode(30);root1.right.right=newNode(3);// Construct Tree root2// 10// / \// 4 6// \// 30Noderoot2=newNode(10);root2.left=newNode(4);root2.right=newNode(6);root2.left.right=newNode(30);System.out.println(isSubTree(root1,root2)?"true":"false");}}
Python
classNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None# Check if two trees are identicaldefareIdentical(root1,root2):# Both nodes are null → identicalifroot1isNoneandroot2isNone:returnTrue# One is null → not identicalifroot1isNoneorroot2isNone:returnFalse# Check current node and recurse on childrenreturn(root1.data==root2.dataandareIdentical(root1.left,root2.left)andareIdentical(root1.right,root2.right))defisSubTree(root1,root2):# Empty subtree → always trueifroot2isNone:returnTrue# Main tree empty but subtree not → falseifroot1isNone:returnFalse# Match found at current nodeifareIdentical(root1,root2):returnTrue# Otherwise, search in left and rightreturn(isSubTree(root1.left,root2)orisSubTree(root1.right,root2))if__name__=="__main__":# Construct Tree root1# 26# / \# 10 3# / \ \# 4 6 3# \# 30root1=Node(26)root1.left=Node(10)root1.right=Node(3)root1.left.left=Node(4)root1.left.right=Node(6)root1.left.left.right=Node(30)root1.right.right=Node(3)# Construct Tree root2# 10# / \# 4 6# \# 30root2=Node(10)root2.left=Node(4)root2.right=Node(6)root2.left.right=Node(30)print("true"ifisSubTree(root1,root2)else"false")
C#
usingSystem;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intvalue){data=value;left=right=null;}}classGFG{// Check if two trees are identicalstaticboolAreIdentical(Noderoot1,Noderoot2){// Both nodes are null → identicalif(root1==null&&root2==null)returntrue;// One is null → not identicalif(root1==null||root2==null)returnfalse;// Check current node and recurse on childrenreturn(root1.data==root2.data&&AreIdentical(root1.left,root2.left)&&AreIdentical(root1.right,root2.right));}staticboolisSubTree(Noderoot1,Noderoot2){// Empty subtree → always trueif(root2==null)returntrue;// Main tree empty but subtree not → falseif(root1==null)returnfalse;// Match found at current nodeif(AreIdentical(root1,root2))returntrue;// Otherwise, search in left and rightreturnisSubTree(root1.left,root2)||isSubTree(root1.right,root2);}staticvoidMain(){// Construct Tree root1// 26// / \// 10 3// / \ \// 4 6 3// \// 30Noderoot1=newNode(26);root1.left=newNode(10);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(6);root1.left.left.right=newNode(30);root1.right.right=newNode(3);// Construct Tree root2// 10// / \// 4 6// \// 30Noderoot2=newNode(10);root2.left=newNode(4);root2.right=newNode(6);root2.left.right=newNode(30);Console.WriteLine(isSubTree(root1,root2)?"true":"false");}}
JavaScript
classNode{constructor(value){this.data=value;this.left=null;this.right=null;}}// Check if two trees are identicalfunctionareIdentical(root1,root2){// Both nodes are null → identicalif(root1===null&&root2===null)returntrue;// One is null → not identicalif(root1===null||root2===null)returnfalse;// Check current node and recurse on childrenreturn(root1.data===root2.data&&areIdentical(root1.left,root2.left)&&areIdentical(root1.right,root2.right));}functionisSubTree(root1,root2){// Empty subtree → always trueif(root2===null)returntrue;// Main tree empty but subtree not → falseif(root1===null)returnfalse;// Match found at current nodeif(areIdentical(root1,root2))returntrue;// Otherwise, search in left and rightreturnisSubTree(root1.left,root2)||isSubTree(root1.right,root2);}// Driver Code// Construct Tree root1// 26// / \// 10 3// / \ \// 4 6 3// \// 30constroot1=newNode(26);root1.left=newNode(10);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(6);root1.left.left.right=newNode(30);root1.right.right=newNode(3);// Construct Tree root2// 10// / \// 4 6// \// 30constroot2=newNode(10);root2.left=newNode(4);root2.right=newNode(6);root2.left.right=newNode(30);console.log(isSubTree(root1,root2)?"true":"false");
Output
true
[Better Approach] Using String Serialisation & Substring Matching - O(n*m) Time and O(n+m) Space
Convert both trees into strings using preorder traversal, and include a special marker (like #) for every null node to preserve the exact structure of the tree. This ensures that different tree structures do not produce the same serialised string. Once both trees are serialised, check if the serialised string of root2 is a substring of the serialised string of root1. If it is found, then root2 is a subtree of root1.
Why this works?
Preorder traversal visits nodes in root => left => right order, so the relative position of each node is preserved in the serialised string.
Adding null markers (#) for missing children and a separator (,) for values ensure that the exact structure of the tree is captured along with the node values.
Because both node values and structure are recorded, each tree gets a unique serialised representation.
This prevents false matches, since two different trees cannot produce the same serialised string.
After serialisation, the subtree check reduces to a simple substring search between the two strings.
While serializing a binary tree with n nodes using preorder traversal, we include a null marker (#) for every null child.
A binary tree with n nodes has exactly (n+1) null child => (n+1) null markers. So, the serialized string contains n node values and (n + 1) null markers.
Total number of items = n + (n+1) = 2n + 1. We add separator (,) also to ensure that concatenation of two node values is not treated as a third value in the string. So total items become (2n + 1) + (2n for separators). Hence, space required = O(4n + 1) ≈ O(n).
C++
#include<iostream>#include<string>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};// Serialize tree using preorder with null markersvoidserialize(Node*root,string&s){// Null node → add markerif(root==nullptr){s+="# ";return;}// Add current nodes+=to_string(root->data)+" ";// Recurse on left and rightserialize(root->left,s);serialize(root->right,s);}boolisSubTree(Node*root1,Node*root2){strings1="",s2="";// Serialize both treesserialize(root1,s1);serialize(root2,s2);// Check substringreturn(s1.find(s2)!=string::npos);}intmain(){// Construct Tree root1// 26// / \ // 10 3// / \ \ // 4 6 3// \ // 30Node*root1=newNode(26);root1->left=newNode(10);root1->right=newNode(3);root1->left->left=newNode(4);root1->left->right=newNode(6);root1->left->left->right=newNode(30);root1->right->right=newNode(3);// Construct Tree root2// 10// / \ // 4 6// \ // 30Node*root2=newNode(10);root2->left=newNode(4);root2->right=newNode(6);root2->left->right=newNode(30);if(isSubTree(root1,root2))cout<<"true";elsecout<<"false";return0;}
Java
importjava.util.*;classNode{intdata;Nodeleft,right;Node(intvalue){data=value;left=right=null;}}classGFG{// Serialize tree using preorder with null markersstaticvoidserialize(Noderoot,StringBuilders){// Null node → add markerif(root==null){s.append("# ");return;}// Add current nodes.append(root.data).append(" ");// Recurse on left and rightserialize(root.left,s);serialize(root.right,s);}staticbooleanisSubTree(Noderoot1,Noderoot2){StringBuilders1=newStringBuilder();StringBuilders2=newStringBuilder();// Serialize both treesserialize(root1,s1);serialize(root2,s2);// Check substringreturns1.toString().contains(s2.toString());}publicstaticvoidmain(String[]args){// Construct Tree root1// 26// / \// 10 3// / \ \// 4 6 3// \// 30Noderoot1=newNode(26);root1.left=newNode(10);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(6);root1.left.left.right=newNode(30);root1.right.right=newNode(3);// Construct Tree root2// 10// / \// 4 6// \// 30Noderoot2=newNode(10);root2.left=newNode(4);root2.right=newNode(6);root2.left.right=newNode(30);if(isSubTree(root1,root2))System.out.println("true");elseSystem.out.println("false");}}
Python
classNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None# Serialize tree using preorder with null markersdefserialize(root,s):# Null node → add markerifrootisNone:s.append("# ")return# Add current nodes.append(str(root.data)+" ")# Recurse on left and rightserialize(root.left,s)serialize(root.right,s)defisSubTree(root1,root2):s1=[]s2=[]# Serialize both treesserialize(root1,s1)serialize(root2,s2)# Convert to stringstr1="".join(s1)str2="".join(s2)# Check substringreturnstr2instr1if__name__=="__main__":# Construct Tree root1# 26# / \# 10 3# / \ \# 4 6 3# \# 30root1=Node(26)root1.left=Node(10)root1.right=Node(3)root1.left.left=Node(4)root1.left.right=Node(6)root1.left.left.right=Node(30)root1.right.right=Node(3)# Construct Tree root2# 10# / \# 4 6# \# 30root2=Node(10)root2.left=Node(4)root2.right=Node(6)root2.left.right=Node(30)print("true"ifisSubTree(root1,root2)else"false")
C#
usingSystem;usingSystem.Text;classNode{publicintdata;publicNodeleft,right;publicNode(intvalue){data=value;left=right=null;}}classGFG{// Serialize tree using preorder with null markersstaticvoidserialize(Noderoot,StringBuilders){// Null node → add markerif(root==null){s.Append("# ");return;}// Add current nodes.Append(root.data+" ");// Recurse on left and rightserialize(root.left,s);serialize(root.right,s);}staticboolisSubTree(Noderoot1,Noderoot2){StringBuilders1=newStringBuilder();StringBuilders2=newStringBuilder();// Serialize both treesserialize(root1,s1);serialize(root2,s2);// Check substringreturns1.ToString().Contains(s2.ToString());}staticvoidMain(){// Construct Tree root1// 26// / \// 10 3// / \ \// 4 6 3// \// 30Noderoot1=newNode(26);root1.left=newNode(10);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(6);root1.left.left.right=newNode(30);root1.right.right=newNode(3);// Construct Tree root2// 10// / \// 4 6// \// 30Noderoot2=newNode(10);root2.left=newNode(4);root2.right=newNode(6);root2.left.right=newNode(30);Console.WriteLine(isSubTree(root1,root2)?"true":"false");}}
JavaScript
classNode{constructor(value){this.data=value;this.left=null;this.right=null;}}// Serialize tree using preorder with null markersfunctionserialize(root,arr){// Null node → add markerif(root===null){arr.push("# ");return;}// Add current nodearr.push(root.data+" ");// Recurse on left and rightserialize(root.left,arr);serialize(root.right,arr);}// Check if root2 is a subtree of root1functionisSubTree(root1,root2){lets1=[];lets2=[];// Serialize both treesserialize(root1,s1);serialize(root2,s2);// Convert to stringletstr1=s1.join("");letstr2=s2.join("");// Check substringreturnstr1.includes(str2);}// Driver Code// Construct Tree root1// 26// / \// 10 3// / \ \// 4 6 3// \// 30letroot1=newNode(26);root1.left=newNode(10);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(6);root1.left.left.right=newNode(30);root1.right.right=newNode(3);// Construct Tree root2// 10// / \// 4 6// \// 30letroot2=newNode(10);root2.left=newNode(4);root2.right=newNode(6);root2.left.right=newNode(30);console.log(isSubTree(root1,root2)?"true":"false");
Output
true
[Expected Approach] Using String Serialisation & KMP algorithm - O(n+m) Time and O(n+m) Space
This is mainly an optimization over the above approach. The idea is to use KMP algorithm for substring check to ensure that we have overall linear time complexity. Similar to this approach another methods can also be used for substring matching like Boyer–Moore and Trie-based matching.
C++
#include<iostream>#include<vector>#include<string>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};// Serialize tree using preorder with null markersvoidserialize(Node*root,string&s){// Null node => add markerif(root==nullptr){s+="# ";return;}// Add current nodes+=to_string(root->data)+" ";// Recurse on left and rightserialize(root->left,s);serialize(root->right,s);}// Build LPS array for KMPvector<int>buildLPS(string&pattern){intm=pattern.length();vector<int>lps(m,0);intlen=0,i=1;while(i<m){if(pattern[i]==pattern[len]){lps[i++]=++len;}else{if(len!=0)len=lps[len-1];elsei++;}}returnlps;}// KMP search: check if pattern exists in textboolkmpSearch(string&text,string&pattern){vector<int>lps=buildLPS(pattern);inti=0,j=0;while(i<text.length()){// Characters match => move bothif(text[i]==pattern[j]){i++;j++;}// Full pattern matchedif(j==pattern.length())returntrue;// Mismatch after some matcheselseif(i<text.length()&&text[i]!=pattern[j]){if(j!=0)j=lps[j-1];elsei++;}}returnfalse;}boolisSubTree(Node*root1,Node*root2){// Serialize both treesstrings1="",s2="";serialize(root1,s1);serialize(root2,s2);// Apply KMP to check substringreturnkmpSearch(s1,s2);}intmain(){// Construct Tree root1// 26// / \ // 10 3// / \ \ // 4 6 3// \ // 30Node*root1=newNode(26);root1->left=newNode(10);root1->right=newNode(3);root1->left->left=newNode(4);root1->left->right=newNode(6);root1->left->left->right=newNode(30);root1->right->right=newNode(3);// Construct Tree root2// 10// / \ // 4 6// \ // 30Node*root2=newNode(10);root2->left=newNode(4);root2->right=newNode(6);root2->left->right=newNode(30);cout<<(isSubTree(root1,root2)?"true":"false");return0;}
Java
importjava.util.*;classNode{intdata;Nodeleft,right;Node(intvalue){data=value;left=right=null;}}classGFG{// Serialize tree using preorder with null markersvoidserialize(Noderoot,StringBuilders){// Null node => add markerif(root==null){s.append("# ");return;}// Add current nodes.append(root.data).append(" ");// Recurse on left and rightserialize(root.left,s);serialize(root.right,s);}// Build LPS array for KMPint[]buildLPS(Stringpattern){intm=pattern.length();int[]lps=newint[m];intlen=0,i=1;while(i<m){if(pattern.charAt(i)==pattern.charAt(len)){lps[i++]=++len;}else{if(len!=0)len=lps[len-1];elsei++;}}returnlps;}// KMP searchbooleankmpSearch(Stringtext,Stringpattern){int[]lps=buildLPS(pattern);inti=0,j=0;while(i<text.length()){// Match => move bothif(text.charAt(i)==pattern.charAt(j)){i++;j++;}// Full match foundif(j==pattern.length())returntrue;// Mismatch after matchelseif(i<text.length()&&text.charAt(i)!=pattern.charAt(j)){if(j!=0)j=lps[j-1];elsei++;}}returnfalse;}booleanisSubTree(Noderoot1,Noderoot2){StringBuilders1=newStringBuilder();StringBuilders2=newStringBuilder();// Serialize both treesserialize(root1,s1);serialize(root2,s2);// Apply KMPreturnkmpSearch(s1.toString(),s2.toString());}publicstaticvoidmain(String[]args){// Construct Tree root1// 26// / \// 10 3// / \ \// 4 6 3// \// 30Noderoot1=newNode(26);root1.left=newNode(10);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(6);root1.left.left.right=newNode(30);root1.right.right=newNode(3);// Construct Tree root2// 10// / \// 4 6// \// 30Noderoot2=newNode(10);root2.left=newNode(4);root2.right=newNode(6);root2.left.right=newNode(30);GFGobj=newGFG();System.out.println(obj.isSubTree(root1,root2)?"true":"false");}}
Python
classNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None# Serialize tree using preorder with null markersdefserialize(root,s):# Null node => add markerifrootisNone:s.append("#")return# Add current nodes.append(str(root.data))# Recurse on left and rightserialize(root.left,s)serialize(root.right,s)# Build LPS array for KMPdefbuildLPS(pattern):lps=[0]*len(pattern)length=0i=1whilei<len(pattern):ifpattern[i]==pattern[length]:length+=1lps[i]=lengthi+=1else:iflength!=0:length=lps[length-1]else:i+=1returnlps# KMP searchdefkmpSearch(text,pattern):lps=buildLPS(pattern)i=j=0whilei<len(text):# Match => move bothiftext[i]==pattern[j]:i+=1j+=1# Full match foundifj==len(pattern):returnTrue# Mismatch after matchelifi<len(text)andtext[i]!=pattern[j]:ifj!=0:j=lps[j-1]else:i+=1returnFalsedefisSubTree(root1,root2):s1=[]s2=[]# Serialize both treesserialize(root1,s1)serialize(root2,s2)# Convert to stringstr1=" ".join(s1)str2=" ".join(s2)# Apply KMPreturnkmpSearch(str1,str2)if__name__=="__main__":# Construct Tree root1# 26# / \# 10 3# / \ \# 4 6 3# \# 30root1=Node(26)root1.left=Node(10)root1.right=Node(3)root1.left.left=Node(4)root1.left.right=Node(6)root1.left.left.right=Node(30)root1.right.right=Node(3)# Construct Tree root2# 10# / \# 4 6# \# 30root2=Node(10)root2.left=Node(4)root2.right=Node(6)root2.left.right=Node(30)print("true"ifisSubTree(root1,root2)else"false")
C#
usingSystem;usingSystem.Text;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intvalue){data=value;left=right=null;}}classGFG{// Serialize tree using preorder with null markersstaticvoidserialize(Noderoot,StringBuilders){// Null node => add markerif(root==null){s.Append("# ");return;}// Add current nodes.Append(root.data+" ");// Recurse on left and rightserialize(root.left,s);serialize(root.right,s);}// Build LPS array for KMPstaticint[]buildLPS(stringpattern){intm=pattern.Length;int[]lps=newint[m];intlen=0,i=1;while(i<m){if(pattern[i]==pattern[len]){lps[i++]=++len;}else{if(len!=0)len=lps[len-1];elsei++;}}returnlps;}// KMP searchstaticboolkmpSearch(stringtext,stringpattern){int[]lps=buildLPS(pattern);inti=0,j=0;while(i<text.Length){// Match => move bothif(text[i]==pattern[j]){i++;j++;}// Full match foundif(j==pattern.Length)returntrue;// Mismatch after matchelseif(i<text.Length&&text[i]!=pattern[j]){if(j!=0)j=lps[j-1];elsei++;}}returnfalse;}// Check if root2 is a subtree of root1staticboolisSubTree(Noderoot1,Noderoot2){StringBuilders1=newStringBuilder();StringBuilders2=newStringBuilder();// Serialize both treesserialize(root1,s1);serialize(root2,s2);// Apply KMPreturnkmpSearch(s1.ToString(),s2.ToString());}staticvoidMain(){// Construct Tree root1// 26// / \// 10 3// / \ \// 4 6 3// \// 30Noderoot1=newNode(26);root1.left=newNode(10);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(6);root1.left.left.right=newNode(30);root1.right.right=newNode(3);// Construct Tree root2// 10// / \// 4 6// \// 30Noderoot2=newNode(10);root2.left=newNode(4);root2.right=newNode(6);root2.left.right=newNode(30);Console.WriteLine(isSubTree(root1,root2)?"true":"false");}}
JavaScript
classNode{constructor(value){this.data=value;this.left=null;this.right=null;}}// Serialize tree using preorder with null markersfunctionserialize(root,arr){// Null node => add markerif(root===null){arr.push("# ");return;}// Add current nodearr.push(root.data+" ");// Recurse on left and rightserialize(root.left,arr);serialize(root.right,arr);}// Build LPS array for KMPfunctionbuildLPS(pattern){constlps=newArray(pattern.length).fill(0);letlen=0,i=1;while(i<pattern.length){if(pattern[i]===pattern[len]){lps[i++]=++len;}else{if(len!==0)len=lps[len-1];elsei++;}}returnlps;}// KMP searchfunctionkmpSearch(text,pattern){constlps=buildLPS(pattern);leti=0,j=0;while(i<text.length){// Match => move bothif(text[i]===pattern[j]){i++;j++;}// Full match foundif(j===pattern.length)returntrue;// Mismatch after matchelseif(i<text.length&&text[i]!==pattern[j]){if(j!==0)j=lps[j-1];elsei++;}}returnfalse;}functionisSubTree(root1,root2){lets1=[];lets2=[];// Serialize both treesserialize(root1,s1);serialize(root2,s2);// Convert to stringletstr1=s1.join("");letstr2=s2.join("");// Apply KMPreturnkmpSearch(str1,str2);}// Driver Code// Construct Tree root1// 26// / \// 10 3// / \ \// 4 6 3// \// 30letroot1=newNode(26);root1.left=newNode(10);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(6);root1.left.left.right=newNode(30);root1.right.right=newNode(3);// Construct Tree root2// 10// / \// 4 6// \// 30letroot2=newNode(10);root2.left=newNode(4);root2.right=newNode(6);root2.left.right=newNode(30);console.log(isSubTree(root1,root2)?"true":"false");