Banana-Leopard/TASTY huggingface dataset:
# Python3 program to delete element in binary tree
 
# class to create a node with data, left child and right child.
 
 
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Inorder traversal of a binary tree
 
 
def inorder(temp):
    if(not temp):
        return
    inorder(temp.left)
    print(temp.data, end=" ")
    inorder(temp.right)
 
 
def deletion(root, key):
    if(root == None):
        return None
    if(root.left == None and root.right == None):
        if(root.data == key):
            return None
        else:
            return root
 
    key_node = None
    temp = None
    last = None
    q = []
    q.append(root)
    # Do level order traversal to find deepest
    # node(temp), node to be deleted (key_node)
    # and parent of deepest node(last)
    while(len(q)):
 
        temp = q.pop(0)
 
        if(temp.data == key):
            key_node = temp
        if(temp.left):
 
            last = temp  # storing the parent node
            q.append(temp.left)
 
        if(temp.right):
 
            last = temp  # storing the parent node
            q.append(temp.right)
 
    if(key_node != None):
 
        key_node.data = temp.data  # replacing key_node's data to deepest node's data
        if(last.right == temp):
            last.right = None
        else:
            last.left = None
 
    return root
 
 
# Driver code
if __name__ == '__main__':
    root = Node(9)
    root.left = Node(2)
    root.left.left = Node(4)
    root.left.right = Node(7)
    root.right = Node(8)
 
    print("Inorder traversal before deletion : ", end="")
    inorder(root)
 
    key = 7
    root = deletion(root, key)
    print()
    print("Inorder traversal after deletion : ", end="")
    inorder(root)
 
# This code is contributed by Abhijeet Kumar(abhijeet19403)

Time complexity: linear
Space complexity: linear
# Python3 implementation of tree using array
# numbering starting from 0 to n-1.
tree = [None] * 10
 
 
def root(key):
    if tree[0] != None:
        print("Tree already had root")
    else:
        tree[0] = key
 
 
def set_left(key, parent):
    if tree[parent] == None:
        print("Can't set child at", (parent * 2) + 1, ", no parent found")
    else:
        tree[(parent * 2) + 1] = key
 
 
def set_right(key, parent):
    if tree[parent] == None:
        print("Can't set child at", (parent * 2) + 2, ", no parent found")
    else:
        tree[(parent * 2) + 2] = key
 
 
def print_tree():
    for i in range(10):
        if tree[i] != None:
            print(tree[i], end="")
        else:
            print("-", end="")
    print()
 
 
# Driver Code
root('A')
set_right('C', 0)
set_left('D', 1)
set_right('E', 1)
set_right('F', 2)
print_tree()
 
# This code is contributed by Gaurav Kumar Tailor

Time complexity: logn
Space complexity: linear
# Python3 program to check foldable binary tree
 
#  A binary tree node has data,
# pointer to left child and a
# pointer to right child
 
 
class newNode:
    def __init__(self, d):
        self.data = d
        self.left = None
        self.right = None
 
# Returns true if the given
# tree is foldable
 
 
def isFoldable(node):
 
    # base case
    if node == None:
        return true
 
    # convert left subtree to its mirror
    mirror(node.left)
 
    # Compare the structures of the right subtree and mirrored
    # left subtree
    res = isStructSame(node.left, node.right)
 
    # Get the original tree back
    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:
 
        # do the subtrees
        mirror(node.left)
        mirror(node.right)
 
        # swap the pointers in this node
        temp = node.left
        node.left = node.right
        node.right = temp
 
 
# Driver Code
if __name__ == '__main__':
 
    '''
    The constructed binary tree is
             1
           /   \
          2     3
           \    /
            4  5
    '''
    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")

Time complexity: linear
Space complexity: linear
# Python3 program to check
# foldable binary tree
 
# Utility function to create a new
# tree node
 
 
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
 
# Returns true if the given tree can be folded
 
 
def IsFoldable(root):
    if (root == None):
        return True
    return IsFoldableUtil(root.left, root.right)
 
 
# A utility function that checks
# if trees with roots as n1 and n2
# are mirror of each other
def IsFoldableUtil(n1, n2):
    # If both left and right subtrees are NULL,
    # then return true
    if n1 == None and n2 == None:
        return True
 
    # If one of the trees is NULL and other is not,
    # then return false
    if n1 == None or n2 == None:
        return False
 
    # Otherwise check if left and
    # right subtrees are mirrors of
    # their counterparts
 
    d1 = IsFoldableUtil(n1.left, n2.right)
    d2 = IsFoldableUtil(n1.right, n2.left)
    return d1 and d2
 
 
# Driver code
if __name__ == "__main__":
 
    """ The constructed binary tree is 
    1 
    / \ 
    2 3 
    \ / 
    4 5 
"""
    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")
 
# This code is contributed by
# Anupam Baranwal(anupambaranwal)

Time complexity: linear
Space complexity: linear
# class to create a node with key, left child and right child.
class Node:
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None
 
 
# Function to find whether the tree is foldable
def isFoldable(root):
 
     # Queue to store visited nodes
    q = []
 
    # Initially add the left and right nodes of root
    if root != None:
        q.append(root.left)
        q.append(root.right)
 
    while (len(q) != 0):
 
        # Remove the front 2 nodes to
        # check for None condition
        p = q.pop(0)
        r = q.pop(0)
 
        # If both are None, continue and check
        # the further elements
        if (p == None and r == None):
            continue
 
        # If one of them is not None, then return False
        if ((p == None and r != None) or (p != None and r == None)):
            return False
 
        ''' Insert in the same order:
            1. left of left subtree
            2. right of right subtree
            3. right of left subtree
            4. left of right subtree 
        '''
        q.append(p.left)
        q.append(r.right)
        q.append(p.right)
        q.append(r.left)
 
    # Only if the tree is foldable
    return True
 
 
# Driver code
# Insert data into the tree
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.right.left = Node(4)
root.left.right = Node(5)
 
# Function call
if isFoldable(root):
    print("tree is foldable")
else:
    print("tree is not foldable")
 
    # This code is contributed by mariuscristiancapatina

Time complexity: linear
Space complexity: linear
# Python program to evaluate expression tree
 
# Class to represent the nodes of syntax tree
 
 
class node:
    def __init__(self, value):
        self.left = None
        self.data = value
        self.right = None
 
# This function receives a node of the syntax tree
# and recursively evaluate it
 
 
def evaluateExpressionTree(root):
 
    # empty tree
    if root is None:
        return 0
 
    # leaf node
    if root.left is None and root.right is None:
        return int(root.data)
 
    # evaluate left tree
    left_sum = evaluateExpressionTree(root.left)
 
    # evaluate right tree
    right_sum = evaluateExpressionTree(root.right)
 
    # check which operation to apply
    if root.data == '+':
        return left_sum + right_sum
 
    elif root.data == '-':
        return left_sum - right_sum
 
    elif root.data == '*':
        return left_sum * right_sum
 
    else:
        return left_sum // right_sum
 
 
# Driver function to test above problem
if __name__ == '__main__':
 
    # creating a sample tree
    root = node('+')
    root.left = node('*')
    root.left.left = node('5')
    root.left.right = node('-4')
    root.right = node('-')
    root.right.left = node('100')
    root.right.right = node('20')
    print (evaluateExpressionTree(root))
 
    root = None
 
    # creating a sample tree
    root = node('+')
    root.left = node('*')
    root.left.left = node('5')
    root.left.right = node('4')
    root.right = node('-')
    root.right.left = node('100')
    root.right.right = node('/')
    root.right.right.left = node('20')
    root.right.right.right = node('2')
    print (evaluateExpressionTree(root))
 
# This code is contributed by Harshit Sidhwa

Time complexity: linear
Space complexity: constant
# Python program to do inorder traversal without recursion
 
# A binary tree node
class Node:
     
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Iterative function for inorder tree traversal
def inOrder(root):
     
    # Set current to root of binary tree
    current = root
    stack = [] # initialize stack
     
    while True:
         
        # Reach the left most Node of the current Node
        if current is not None:
             
            # Place pointer to a tree node on the stack
            # before traversing the node's left subtree
            stack.append(current)
         
            current = current.left
 
         
        # BackTrack from the empty subtree and visit the Node
        # at the top of the stack; however, if the stack is
        # empty you are done
        elif(stack):
            current = stack.pop()
            print(current.data, end=" ") # Python 3 printing
         
            # We have visited the node and its left
            # subtree. Now, it's right subtree's turn
            current = current.right
 
        else:
            break
      
    print()
 
# Driver program to test above function
 
""" Constructed binary tree is
            1
          /   \
         2     3
       /  \
      4    5   """
 
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
 
inOrder(root)
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: linear
Space complexity: linear
"""Python3 program for finding postorder
traversal of BST from preorder traversal"""
 
INT_MIN = -2**31
INT_MAX = 2**31
 
# Function to find postorder traversal
# from preorder traversal.
 
 
def findPostOrderUtil(pre, n, minval,
                      maxval, preIndex):
 
    # If entire preorder array is traversed
    # then return as no more element is left
    # to be added to post order array.
    if (preIndex[0] == n):
        return
 
    # If array element does not lie in
    # range specified, then it is not
    # part of current subtree.
    if (pre[preIndex[0]] < minval or
            pre[preIndex[0]] > maxval):
        return
 
    # Store current value, to be printed later,
    # after printing left and right subtrees.
    # Increment preIndex to find left and right
    # subtrees, and pass this updated value to
    # recursive calls.
    val = pre[preIndex[0]]
    preIndex[0] += 1
 
    # All elements with value between minval
    # and val lie in left subtree.
    findPostOrderUtil(pre, n, minval,
                      val, preIndex)
 
    # All elements with value between val
    # and maxval lie in right subtree.
    findPostOrderUtil(pre, n, val,
                      maxval, preIndex)
 
    print(val, end=" ")
 
# Function to find postorder traversal.
 
 
def findPostOrder(pre, n):
 
    # To store index of element to be
    # traversed next in preorder array.
    # This is passed by reference to
    # utility function.
    preIndex = [0]
 
    findPostOrderUtil(pre, n, INT_MIN,
                      INT_MAX, preIndex)
 
 
# Driver Code
if __name__ == '__main__':
    pre = [40, 30, 35, 80, 100]
 
    n = len(pre)
 
    # Calling function
    findPostOrder(pre, n)
 
# This code is contributed by
# SHUBHAMSINGH10

Time complexity: linear
Space complexity: linear
# Recursive Python program for level
# order traversal of Binary Tree
 
# A node structure
 
 
class Node:
 
    # A utility function to create a new node
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None
 
 
# Function to  print level order traversal of tree
def printLevelOrder(root):
    h = height(root)
    for i in range(1, h+1):
        printCurrentLevel(root, i)
 
 
# Print nodes at a current level
def printCurrentLevel(root, level):
    if root is None:
        return
    if level == 1:
        print(root.data, end=" ")
    elif level > 1:
        printCurrentLevel(root.left, level-1)
        printCurrentLevel(root.right, level-1)
 
 
""" Compute the height of a tree--the number of nodes
    along the longest path from the root node down to
    the farthest leaf node
"""
 
 
def height(node):
    if node is None:
        return 0
    else:
        # Compute the height of each subtree
        lheight = height(node.left)
        rheight = height(node.right)
 
        # Use the larger one
        if lheight > rheight:
            return lheight+1
        else:
            return rheight+1
 
 
# Driver program to test above function
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
 
print("Level order traversal of binary tree is -")
printLevelOrder(root)
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: quadratic
Space complexity: linear
# Python program to print level
# order traversal using Queue
 
# A node structure
 
 
class Node:
    # A utility function to create a new node
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None
 
# Iterative Method to print the
# height of a binary tree
 
 
def printLevelOrder(root):
    # Base Case
    if root is None:
        return
 
    # Create an empty queue
    # for level order traversal
    queue = []
 
    # Enqueue Root and initialize height
    queue.append(root)
 
    while(len(queue) > 0):
 
        # Print front of queue and
        # remove it from queue
        print(queue[0].data, end = " ")
        node = queue.pop(0)
 
        # Enqueue left child
        if node.left is not None:
            queue.append(node.left)
 
        # Enqueue right child
        if node.right is not None:
            queue.append(node.right)
 
 
# Driver Program to test above function
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
 
print("Level Order Traversal of binary tree is -")
printLevelOrder(root)
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: linear
Space complexity: linear
# Python3 program for recursive level order
# traversal in spiral form
 
 
class newNode:
 
    # Construct to create a newNode
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None
 
 
""" Function to print spiral traversal of a tree"""
 
 
def printSpiral(root):
 
    h = height(root)
 
    """ltr Left to Right. If this variable
    is set, then the given level is traversed
    from left to right. """
    ltr = False
    for i in range(1, h + 1):
 
        printGivenLevel(root, i, ltr)
 
        """Revert ltr to traverse next level
           in opposite order"""
        ltr = not ltr
 
 
""" Print nodes at a given level """
 
 
def printGivenLevel(root, level, ltr):
 
    if(root == None):
        return
    if(level == 1):
        print(root.data, end=" ")
    elif (level > 1):
 
        if(ltr):
            printGivenLevel(root.left, level - 1, ltr)
            printGivenLevel(root.right, level - 1, ltr)
 
        else:
            printGivenLevel(root.right, level - 1, ltr)
            printGivenLevel(root.left, level - 1, ltr)
 
 
""" Compute the "height" of a tree -- the number of
    nodes along the longest path from the root node
    down to the farthest leaf node."""
 
 
def height(node):
 
    if (node == None):
        return 0
    else:
 
        """ compute the height of each subtree """
        lheight = height(node.left)
        rheight = height(node.right)
 
        """ use the larger one """
        if (lheight > rheight):
            return(lheight + 1)
        else:
            return(rheight + 1)
 
 
# Driver Code
if __name__ == '__main__':
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(7)
    root.left.right = newNode(6)
    root.right.left = newNode(5)
    root.right.right = newNode(4)
    print("Spiral Order traversal of binary tree is")
    printSpiral(root)
 
# This code is contributed
# by SHUBHAMSINGH10

Time complexity: quadratic
Space complexity: linear
# Python3 implementation of a O(n) time
# method for spiral order traversal
 
# A class to create a new node
 
 
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
 
def printSpiral(root):
    if (root == None):
        return  # None check
 
    # Create two stacks to store
    # alternate levels
    s1 = []  # For levels to be printed
    # from right to left
    s2 = []  # For levels to be printed
    # from left to right
 
    # append first level to first stack 's1'
    s1.append(root)
 
    # Keep printing while any of the
    # stacks has some nodes
    while not len(s1) == 0 or not len(s2) == 0:
 
        # Print nodes of current level from s1
        # and append nodes of next level to s2
        while not len(s1) == 0:
            temp = s1[-1]
            s1.pop()
            print(temp.data, end=" ")
 
            # Note that is right is appended
            # before left
            if (temp.right):
                s2.append(temp.right)
            if (temp.left):
                s2.append(temp.left)
 
        # Print nodes of current level from s2
        # and append nodes of next level to s1
        while (not len(s2) == 0):
            temp = s2[-1]
            s2.pop()
            print(temp.data, end=" ")
 
            # Note that is left is appended
            # before right
            if (temp.left):
                s1.append(temp.left)
            if (temp.right):
                s1.append(temp.right)
 
 
# Driver Code
if __name__ == '__main__':
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(7)
    root.left.right = newNode(6)
    root.right.left = newNode(5)
    root.right.right = newNode(4)
    print("Spiral Order traversal of",
          "binary tree is ")
    printSpiral(root)
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: linear
# Python3 implementation of above approach
 
# A class to create a new node
from collections import deque
 
 
class newNode:
    def __init__(self, data):
        self.key = data
        self.left = None
        self.right = None
 
 
def spiralPrint(root):
    # Declare a deque
    dq = deque()
 
    # Insert the root of the tree into the deque
    dq.append(root)
 
    # Create a  variable that will switch in each iteration
    reverse = True
 
    # Start iteration
    while (len(dq)):
 
        # Save the size of the deque here itself, as in further steps the size
        # of deque will frequently change
        n = len(dq)
 
        # If we are printing left to right
        if(not reverse):
 
            # Iterate from left to right
            while (n > 0):
                n -= 1
 
                # Insert the child from the back of the deque
                # Left child first
                if (dq[0].left != None):
                    dq.append(dq[0].left)
 
                if (dq[0].right != None):
                    dq.append(dq[0].right)
 
                # Print the current processed element
                print(dq[0].key, end="  ")
                dq.popleft()
 
            # Switch reverse for next traversal
            reverse = not reverse
        else:
 
            # If we are printing right to left
            # Iterate the deque in reverse order and insert the children
            # from the front
            while (n > 0):
                n -= 1
                # Insert the child in the front of the deque
                # Right child first
                if (dq[-1].right != None):
                    dq.appendleft(dq[-1].right)
 
                if (dq[-1].left != None):
                    dq.appendleft(dq[-1].left)
 
                # Print the current processed element
                print(dq[-1].key, end="  ")
                dq.pop()
 
            # Switch reverse for next traversal
            reverse = not reverse
 
 
# Driver Code
if __name__ == '__main__':
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(7)
    root.left.right = newNode(6)
    root.right.left = newNode(5)
    root.right.right = newNode(4)
    print("Spiral Order traversal of",
          "binary tree is :")
    spiralPrint(root)
 
# This code is contributed by Abhijeet Kumar(abhijeet19403)

Time complexity: linear
Space complexity: linear