Banana-Leopard/TASTY huggingface dataset:
MAX = 100
 
# class for a tree node
class Node:
    def __init__(self):
        self.key = ' '
        self.left = None
        self.right = None
 
# A utility function to create a new BST node
def newNode(item):
    temp = Node()
    temp.key = item
    return temp
 
# A utility function to store inorder traversal of tree rooted
# with root in an array arr[]. Note that i is passed as reference
def storeInorder(root, i):
    if (root == None):
        return '$'
    res = storeInorder(root.left, i)
    res += root.key
    res += storeInorder(root.right, i)
    return res
 
# A utility function to store preorder traversal of tree rooted
# with root in an array arr[]. Note that i is passed as reference
def storePreOrder(root, i):
    if (root == None):
        return '$'
    res = root.key
    res += storePreOrder(root.left, i)
    res += storePreOrder(root.right, i)
    return res
 
# This function returns true if S is a subtree of T, otherwise false
def isSubtree(T, S):
    # base cases
    if (S == None):
        return True
    if (T == None):
        return False
 
    # Store Inorder traversals of T and S in inT[0..m-1]
    # and inS[0..n-1] respectively
    m = 0
    n = 0
    inT = storeInorder(T, m)
    inS = storeInorder(S, n)
 
    # If inS[] is not a substring of inT[], return false
    res = True
    if inS in inT:
        res = True
    else:
        res = False
    if(res == False):
        return res
 
    # Store Preorder traversals of T and S in preT[0..m-1]
    # and preS[0..n-1] respectively
    m = 0
    n = 0
    preT = storePreOrder(T, m)
    preS = storePreOrder(S, n)
 
    # If preS[] is not a substring of preT[], return false
    # Else return true
    if preS in preT:
        return True
    else:
        return False
 
# Driver program to test above function
T = newNode('a')
T.left = newNode('b')
T.right = newNode('d')
T.left.left = newNode('c')
T.right.right = newNode('e')
 
S = newNode('a')
S.left = newNode('b')
S.left.left = newNode('c')
S.right = newNode('d')
 
if (isSubtree(T, S)):
    print("Yes: S is a subtree of T")
else:
    print("No: S is NOT a subtree of T")
 
    # This code is contributed by rj13to.

Time complexity: linear
Space complexity: linear
# Python3 program to check if two
# trees are mirror of each other
 
# A binary tree node
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Given two trees, return true
# if they are mirror of each other
def areMirror(a, b):
     
    # Base case : Both empty
    if a is None and b is None:
        return True
     
    # If only one is empty
    if a is None or b is None:
        return False
     
    # Both non-empty, compare them
    # recursively. Note that in
    # recursive calls, we pass left
    # of one tree and right of other tree
    return (a.data == b.data and
            areMirror(a.left, b.right) and
            areMirror(a.right , b.left))
 
# Driver code
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")
 
# This code is contributed by AshishR

Time complexity: linear
Space complexity: logn
# Python3 implementation to check whether 
# the two binary trees are mirrors of each 
# other or not 
  
# Utility function to create and return 
# a new node for a binary tree 
class newNode:
    def __init__(self, data): 
        self.data = data 
        self.left = self.right = None
  
# function to check whether the two binary 
# trees are mirrors of each other or not 
def areMirrors(root1, root2):
    st1 = []
    st2 = []
    while (1):
          
        # iterative inorder traversal of 1st tree 
        # and reverse inorder traversal of 2nd tree 
        while (root1 and root2):
              
            # if the corresponding nodes in the 
            # two traversal have different data 
            # values, then they are not mirrors 
            # of each other. 
            if (root1.data != root2.data): 
                return "No"
                  
            st1.append(root1) 
            st2.append(root2) 
            root1 = root1.left 
            root2 = root2.right
          
        # if at any point one root becomes None and 
        # the other root is not None, then they are 
        # not mirrors. This condition verifies that 
        # structures of tree are mirrors of each other. 
        if (not (root1 == None and root2 == None)): 
            return "No"
              
        if (not len(st1) == 0 and not len(st2) == 0):
            root1 = st1[-1] 
            root2 = st2[-1] 
            st1.pop(-1) 
            st2.pop(-1) 
              
            # we have visited the node and its left 
            # subtree. Now, it's right subtree's turn 
            root1 = root1.right 
              
            # we have visited the node and its right 
            # subtree. Now, it's left subtree's turn 
            root2 = root2.left
          
        # both the trees have been 
        # completely traversed 
        else:
            break
      
    # trees are mirrors of each other 
    return "Yes"
  
# Driver Code
if __name__ == '__main__':
      
    # 1st binary tree formation 
    root1 = newNode(1)         #          1                             
    root1.left = newNode(3)         #     / \     
    root1.right = newNode(2)  #        3    2     
    root1.right.left = newNode(5)#       / \     
    root1.right.right = newNode(4) #  5      4 
      
    # 2nd binary tree formation     
    root2 = newNode(1)        #          1                             
    root2.left = newNode(2)         #     / \     
    root2.right = newNode(3) #        2     3     
    root2.left.left = newNode(4)#  / \         
    root2.left.right = newNode(5)# 4  5         
          
    print(areMirrors(root1, root2))
      
# This code is contributed by pranchalK

Time complexity: linear
Space complexity: linear
# Python3 program to program to check if a
# given Binary Tree is symmetric or not
 
# Helper function that allocates a new
# node with the given data and None
# left and right pairs.                                    
class newNode:
 
    # Constructor to create a new node
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None
 
# function to check if a given
# Binary Tree is symmetric or not
def isSymmetric( root) :
 
    # if tree is empty
    if (root == None) :
        return True
     
    # If it is a single tree node,
    # then it is a symmetric tree.
    if(not root.left and not root.right):
        return True
     
    q = []    
     
    # Add root to queue two times so that
    # it can be checked if either one
    # child alone is NULL or not.
    q.append(root)
    q.append(root)
     
    # To store two nodes for checking
    # their symmetry.
    leftNode = 0
    rightNode = 0
     
    while(not len(q)):
         
        # Remove first two nodes to
        # check their symmetry.
        leftNode = q[0]
        q.pop(0)
         
        rightNode = q[0]
        q.pop(0)
         
        # if both left and right nodes
        # exist, but have different
        # values-. inequality, return False
        if(leftNode.key != rightNode.key):
            return False
         
        # append left child of left subtree
        # node and right child of right 
        # subtree node in queue.
        if(leftNode.left and rightNode.right) :
            q.append(leftNode.left)
            q.append(rightNode.right)
         
        # If only one child is present
        # alone and other is NULL, then
        # tree is not symmetric.
        elif (leftNode.left or rightNode.right) :
            return False
         
        # append right child of left subtree
        # node and left child of right subtree
        # node in queue.
        if(leftNode.right and rightNode.left):
            q.append(leftNode.right)
            q.append(rightNode.left)
         
        # If only one child is present
        # alone and other is NULL, then
        # tree is not symmetric.
        elif(leftNode.right or rightNode.left):
            return False
     
    return True
         
# Driver Code
if __name__ == '__main__':
     
    # Let us construct the Tree
    # shown in the above figure
    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)) :
        print("The given tree is Symmetric")
    else:
        print("The given tree is not Symmetric")
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)

Time complexity: linear
Space complexity: logn
''' A binary tree node has key, pointer to left
   child and a pointer to right child '''
    
class Node:
     
    def __init__(self, key):
         
        self.key=key
        self.left = None
        self.right = None
 
# To create a newNode of tree and return pointer
def newNode(key):
     
    temp = Node(key)
    return temp
 
# Takes two parameters - same initially and
# calls recursively
def  printMiddleLevelUtil(a, b):
 
    # Base case e
    if (a == None or b == None):
        return;
  
    # Fast pointer has reached the leaf so print
    # value at slow pointer
    if ((b.left == None) and (b.right == None)):
        print(a.key, end=' ')
         
        return;
     
    # Recursive call
    # root.left.left and root.left.right will
    # print same value
    # root.right.left and root.right.right
    # will print same value
    # So we use any one of the condition
    if (b.left.left):
        printMiddleLevelUtil(a.left, b.left.left);
        printMiddleLevelUtil(a.right, b.left.left);
     
    else:
        printMiddleLevelUtil(a.left, b.left);
        printMiddleLevelUtil(a.right, b.left);
         
# Main printing method that take a Tree as input
def printMiddleLevel(node):
 
    printMiddleLevelUtil(node, node);
 
# Driver program to test above functions
if __name__=='__main__':
 
  
    n1 = newNode(1);
    n2 = newNode(2);
    n3 = newNode(3);
    n4 = newNode(4);
    n5 = newNode(5);
    n6 = newNode(6);
    n7 = newNode(7);
  
    n2.left = n4;
    n2.right = n5;
    n3.left = n6;
    n3.right = n7;
    n1.left = n2;
    n1.right = n3;
  
    printMiddleLevel(n1);
 
# This code is contributed by rutvik_56

Time complexity: linear
Space complexity: logn
# Python3 program to print the longest
# leaf to leaf path
 
# Tree node structure used in the program
MAX_PATH_SIZE = 1000
 
class Node:
     
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None
 
# Prints given root to leafAllpaths
# with underscores
def printPath(size):
     
    global Allpaths
     
    # Find the minimum horizontal distance
    # value in current root to leafAllpaths
    minimum_Hd = 10**19
 
    p = []
 
    # Find minimum horizontal distance
    for it in range(size):
        p = Allpaths[it]
        minimum_Hd = min(minimum_Hd, p[0])
 
    # Print the root to leafAllpaths with "_"
    # that indicate the related position
    for it in range(size):
         
        # Current tree node
        p = Allpaths[it]
        noOfUnderScores = abs(p[0] - minimum_Hd)
 
        # Print underscore
        for i in range(noOfUnderScores):
            print(end = "_ ")
 
        # Print current key
        print(p[1])
         
    print("==============================")
 
# A utility function print all path from root to leaf
# working of this function is similar to function of
# "Print_vertical_order" : Print paths of binary tree
# in vertical order
# https://www.geeksforgeeks.org/print-binary-tree-vertical-order-set-2/
def printAllPathsUtil(root, HD, order):
     
    # Base case
    global Allpaths
 
    if (root == None):
        return
 
    # Leaf node
    if (root.left == None and root.right == None):
         
        # Add leaf node and then print path
        Allpaths[order] = [HD, root.data]
        printPath(order + 1)
        return
 
    # Store current path information
    Allpaths[order] = [HD, root.data]
 
    # Call left sub_tree
    printAllPathsUtil(root.left, HD - 1, order + 1)
 
    # Call left sub_tree
    printAllPathsUtil(root.right, HD + 1, order + 1)
 
def printAllPaths(root):
     
    global Allpaths
     
    # Base case
    if (root == None):
        return
 
    printAllPathsUtil(root, 0, 0)
 
# Driver code
if __name__ == '__main__':
     
    Allpaths = [ [0, 0]  for i in range(MAX_PATH_SIZE)]
 
    root = Node('A')
    root.left = Node('B')
    root.right = Node('C')
    root.left.left = Node('D')
    root.left.right = Node('E')
    root.right.left = Node('F')
    root.right.right = Node('G')
 
    printAllPaths(root)
 
# This code is contributed by mohit kumar 29

Time complexity: constant
Space complexity: logn
# Recursive Python3 program to print
# odd level nodes
 
# Utility method to create a node
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
 
def printOddNodes(root, isOdd = True):
     
    # If empty tree
    if (root == None):
        return
 
    # If current node is of odd level
    if (isOdd):
        print(root.data, end = " ")
 
    # Recur for children with isOdd
    # switched.
    printOddNodes(root.left, not isOdd)
    printOddNodes(root.right, not isOdd)
 
# Driver code
if __name__ == '__main__':
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(4)
    root.left.right = newNode(5)
    printOddNodes(root)
     
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: linear
# Iterative Python3 program to print odd
# level nodes
 
# A Binary Tree Node
# Utility function to create a
# new tree Node
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
         
# Iterative method to do level order
# traversal line by line
def printOddNodes(root) :
 
    # Base Case
    if (root == None):
        return
 
    # Create an empty queue for 
    # level order traversal
    q = []
 
    # Enqueue root and initialize
    # level as odd
    q.append(root)
    isOdd = True
 
    while (1) :
     
        # nodeCount (queue size) indicates
        # number of nodes at current level.
        nodeCount = len(q)
        if (nodeCount == 0) :
            break
 
        # Dequeue all nodes of current level
        # and Enqueue all nodes of next level
        while (nodeCount > 0):
         
            node = q[0]
            if (isOdd):
                print(node.data, end = " ")
            q.pop(0)
            if (node.left != None) :
                q.append(node.left)
            if (node.right != None) :
                q.append(node.right)
            nodeCount -= 1
             
        isOdd = not isOdd
 
# Driver Code
if __name__ == '__main__':
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(4)
    root.left.right = newNode(5)
    printOddNodes(root)
 
# This code is contributed
# by SHUBHAMSINGH10

Time complexity: linear
Space complexity: linear
# Python3 program to find the all
# full nodes in a given binary tree
 
# Binary Tree Node
""" utility that allocates a newNode
with the given key """
class newNode:
 
    # Construct to create a newNode
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None
 
# Traverses given tree in Inorder
# fashion and prints all nodes that
# have both children as non-empty.
def findFullNode(root) :
 
    if (root != None) :
     
        findFullNode(root.left)
        if (root.left != None and
            root.right != None) :
            print(root.data, end = " ")
        findFullNode(root.right)
 
# Driver Code
if __name__ == '__main__':
 
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(4)
    root.right.left = newNode(5)
    root.right.right = newNode(6)
    root.right.left.right = newNode(7)
    root.right.right.right = newNode(8)
    root.right.left.right.left = newNode(9)
    findFullNode(root)
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)

Time complexity: linear
Space complexity: linear
# Python3 Program to print sum of all
# the elements of a binary tree
 
# Binary Tree Node
class newNode:
 
    # Utility function to create a new node
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None
 
# Function to find sum of all the element
def sumBT(root):
    # sum variable to track the sum of
    # all variables.
    sum = 0
 
    q = []
 
    # Pushing the first level.
    q.append(root)
 
    # Pushing elements at each level from
    # the tree.
    while len(q) > 0:
        temp = q.pop(0)
 
        # After popping each element from queue
        # add its data to the sum variable.
        sum += temp.key
 
        if (temp.left != None):
            q.append(temp.left)
        if temp.right != None:
            q.append(temp.right)
 
    return sum
 
 
# Driver Code
if __name__ == '__main__':
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(4)
    root.left.right = newNode(5)
    root.right.left = newNode(6)
    root.right.right = newNode(7)
    root.right.left.right = newNode(8)
 
    print("Sum of all elements in the binary tree is: ", sumBT(root))
 
# This code is contributed by
# Abhijeet Kumar(abhijeet19403)

Time complexity: linear
Space complexity: linear
# Python3 implementation to find the Sum of
# all the parent nodes having child node x
 
# function to get a new node
class getNode:
    def __init__(self, data):
         
        # put in the data    
        self.data = data
        self.left = self.right = None
 
# function to find the Sum of all the
# parent nodes having child node x
def SumOfParentOfX(root, Sum, x):
     
    # if root == None
    if (not root):
        return
     
    # if left or right child of root is 'x',
    # then add the root's data to 'Sum'
    if ((root.left and root.left.data == x) or
        (root.right and root.right.data == x)):
        Sum[0] += root.data
     
    # recursively find the required parent
    # nodes in the left and right subtree    
    SumOfParentOfX(root.left, Sum, x)
    SumOfParentOfX(root.right, Sum, x)
 
# utility function to find the Sum of all
# the parent nodes having child node x
def SumOfParentOfXUtil(root, x):
    Sum = [0]
    SumOfParentOfX(root, Sum, x)
     
    # required Sum of parent nodes
    return Sum[0]
 
# Driver Code
if __name__ == '__main__':
     
    # binary tree formation
    root = getNode(4)         #     4    
    root.left = getNode(2)         #     / \    
    root.right = getNode(5)         #     2 5    
    root.left.left = getNode(7)     #     / \ / \    
    root.left.right = getNode(2) # 7 2 2 3
    root.right.left = getNode(2)
    root.right.right = getNode(3)
     
    x = 2
     
    print("Sum = ", SumOfParentOfXUtil(root, x))
     
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: linear
# Python3 program to find sum of
# all left leaves
from collections import deque
 
# A binary tree node
class Node:
     
    def __init__(self, x):
         
        self.key = x
        self.left = None
        self.right = None
 
# Return the sum of left leaf nodes
def sumOfLeftLeaves(root):
     
    if (root == None):
        return 0
         
    # A queue of pairs to do bfs traversal
    # and keep track if the node is a left
    # or right child if boolean value
    # is true then it is a left child.
    q = deque()
    q.append([root, 0])
    sum = 0
     
    # Do bfs traversal
    while (len(q) > 0):
        temp = q[0][0]
        is_left_child = q[0][1]
        q.popleft()
         
        # If temp is a leaf node and
        # left child of its parent
        if (not temp.left and
            not temp.right and
            is_left_child):
            sum = sum + temp.key
             
        # If it is not leaf then
        # push its children nodes
        # into queue
        if (temp.left):
             
            # Boolean value is true
            # here because it is left
            # child of its parent
            q.append([temp.left, 1])
             
        if (temp.right):
             
            # Boolean value is false
            # here because it is
            # right child of its parent
            q.append([temp.right, 0])
 
    return sum
 
# Driver Code
if __name__ == '__main__':
     
    root = Node(20)
    root.left = Node(9)
    root.right = Node(49)
    root.right.left = Node(23)
    root.right.right = Node(52)
    root.right.right.left = Node(50)
    root.left.left = Node(5)
    root.left.right = Node(12)
    root.left.right.right = Node(12)
 
    print("Sum of left leaves is",
          sumOfLeftLeaves(root))
 
# This code is contributed by mohit kumar 29

Time complexity: linear
Space complexity: linear
# Python Code to find sum of nodes on the longest path from root to leaf node
# using level order traversal
 
# Building a tree node having left and right pointers set to null initially
class Node:
    def __init__(self, element):
        self.data = element
        self.left = None
        self.right = None
 
# To store current Node,it's level and sum in the path
class Element:
    def __init__(self, data, level, sum):
        self.data = data
        self.level = level
        self.sum = sum
 
 
class Solution:
    def longestPathLeaf(self, root):
 
        # maxSumLevel stores maximum sum so far in the path
        # maxLevel stores maximum level so far
 
        maxSumLevel = root.data
        maxLevel = 0
 
        # queue to implement level order traversal
        que = []
 
        # Each element variable stores the current Node, it's level, sum in the path
        e = Element(root, 0, root.data)
 
        # push the root element
        que.append(e)
 
        # do level order traversal on the tree
        while len(que) != 0:
 
            front = que[0]
            curr = front.data
            del que[0]
 
           # if the level of current front element is greater than the maxLevel so far then update maxSum
            if front.level > maxLevel:
                maxSumLevel = front.sum
                maxLevel = front.level
 
                # if another path competes then update if the sum is greater than the previous path of same height
            elif front.level == maxLevel and front.sum > maxSumLevel:
                maxSumLevel = front.sum
 
                # push the left element if exists
            if curr.left != None:
                e = Element(curr.left, front.level+1, curr.left.data+front.sum)
                que.append(e)
 
                # push the right element if exists
            if curr.right != None:
                e = Element(curr.right, front.level+1,
                            curr.right.data+front.sum)
                que.append(e)
 
        # return the answer
        return maxSumLevel
 
 
# Helper function
if __name__ == '__main__':
    s = Solution()
    root = Node(4)
    root.left = Node(2)
    root.right = Node(5)
    root.left.left = Node(7)
    root.left.right = Node(1)
    root.right.left = Node(2)
    root.right.right = Node(3)
    root.left.right.left = Node(6)
 
    print(s.longestPathLeaf(root))
 
# This code is contributed by Tapesh(tapeshdua420)

Time complexity: linear
Space complexity: linear