Banana-Leopard/TASTY huggingface dataset:
# Python program for special order traversal
 
# A binary tree node
class Node:
    # A constructor for making a new node
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None
 
# Given a perfect binary tree print its node in
# specific order
def printSpecificLevelOrder(root):
    if root is None:
        return
     
    # Let us print root and next level first
    print (root.data,end=" ")
     
    # Since it is perfect Binary tree,
    # one of the node is needed to be checked
    if root.left is not None :
        print (root.left.data,end=" ")
        print (root.right.data,end=" ")
     
    # Do anything more if there are nodes at next level
    # in given perfect Binary Tree
    if root.left.left is None:
        return
 
    # Create a queue and enqueue left and right
    # children of root
    q = []
    q.append(root.left)
    q.append(root.right)
     
    # We process two nodes at a time, so we need
    # two variables to store two front items of queue
    first = None
    second = None
    
    # Traversal loop
    while(len(q) > 0):
 
        # Pop two items from queue
        first = q.pop(0)
        second = q.pop(0)
 
        # Print children of first and second in reverse order
        print (first.left.data,end=" ")
        print (second.right.data,end=" ")
        print (first.right.data,end=" ")
        print (second.left.data,end=" ")
         
        # If first and second have grandchildren,
        # enqueue them in reverse order
        if first.left.left is not None:
            q.append(first.left)
            q.append(second.right)
            q.append(first.right)
            q.append(second.left)
 
# Driver program to test above function
 
# Perfect Binary Tree of Height 4
root = Node(1)
  
root.left= Node(2)
root.right   = Node(3)
  
root.left.left  = Node(4)
root.left.right = Node(5)
root.right.left  = Node(6)
root.right.right = Node(7)
  
root.left.left.left  = Node(8)
root.left.left.right  = Node(9)
root.left.right.left  = Node(10)
root.left.right.right  = Node(11)
root.right.left.left  = Node(12)
root.right.left.right  = Node(13)
root.right.right.left  = Node(14)
root.right.right.right  = Node(15)
  
root.left.left.left.left  = Node(16)
root.left.left.left.right  = Node(17)
root.left.left.right.left  = Node(18)
root.left.left.right.right  = Node(19)
root.left.right.left.left  = Node(20)
root.left.right.left.right  = Node(21)
root.left.right.right.left  = Node(22)
root.left.right.right.right  = Node(23)
root.right.left.left.left  = Node(24)
root.right.left.left.right  = Node(25)
root.right.left.right.left  = Node(26)
root.right.left.right.right  = Node(27)
root.right.right.left.left  = Node(28)
root.right.right.left.right  = Node(29)
root.right.right.right.left  = Node(30)
root.right.right.right.right  = Node(31)
  
print ("Specific Level Order traversal of binary tree is")
printSpecificLevelOrder(root);
  
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: linear
Space complexity: linear
# Python3 program to reverse
# alternate levels of a tree
 
# A Binary Tree Node
# Utility function to create
# a new tree node
class Node:
 
    # Constructor to create a new node
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None
 
def preorder(root1, root2, lvl):
     
    # Base cases
    if (root1 == None or root2 == None):
        return
 
    # Swap subtrees if level is even
    if (lvl % 2 == 0):
        t = root1.key
        root1.key = root2.key
        root2.key = t
 
    # Recur for left and right subtrees
    # (Note : left of root1 is passed and
    # right of root2 in first call and
    # opposite in second call.
    preorder(root1.left, root2.right, lvl + 1)
    preorder(root1.right, root2.left, lvl + 1)
 
# This function calls preorder()
# for left and right children of root
def reverseAlternate(root):
    preorder(root.left, root.right, 0)
 
# Inorder traversal (used to print
# initial and modified trees)
def printInorder(root):
    if (root == None):
        return
    printInorder(root.left)
    print( root.key, end = " ")
    printInorder(root.right)
 
# A utility function to create a new node
def newNode(key):
    temp = Node(' ')
    temp.left = temp.right = None
    temp.key = key
    return temp
 
# Driver Code
if __name__ == '__main__':
    root = newNode('a')
    root.left = newNode('b')
    root.right = newNode('c')
    root.left.left = newNode('d')
    root.left.right = newNode('e')
    root.right.left = newNode('f')
    root.right.right = newNode('g')
    root.left.left.left = newNode('h')
    root.left.left.right = newNode('i')
    root.left.right.left = newNode('j')
    root.left.right.right = newNode('k')
    root.right.left.left = newNode('l')
    root.right.left.right = newNode('m')
    root.right.right.left = newNode('n')
    root.right.right.right = newNode('o')
 
    print( "Inorder Traversal of given tree")
    printInorder(root)
 
    reverseAlternate(root)
 
    print("\nInorder Traversal of modified tree")
    printInorder(root)
 
# This code is contributed by Arnab Kundu

Time complexity: linear
Space complexity: logn
# Python program to perform iterative preorder traversal
 
# 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
 
# An iterative process to print preorder traversal of BT
def iterativePreorder(root):
     
    # Base CAse
    if root is None:
        return
 
    # create an empty stack and push root to it
    nodeStack = []
    nodeStack.append(root)
 
    # Pop all items one by one. Do following for every popped item
    # a) print it
    # b) push its right child
    # c) push its left child
    # Note that right child is pushed first so that left
    # is processed first */
    while(len(nodeStack) > 0):
         
        # Pop the top item from stack and print it
        node = nodeStack.pop()
        print (node.data, end=" ")
         
        # Push right and left children of the popped node
        # to stack
        if node.right is not None:
            nodeStack.append(node.right)
        if node.left is not None:
            nodeStack.append(node.left)
     
# Driver program to test above function
root = Node(10)
root.left = Node(8)
root.right = Node(2)
root.left.left = Node(3)
root.left.right = Node(5)
root.right.left = Node(2)
iterativePreorder(root)
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: linear
Space complexity: logn
# Tree Node
class Node:
 
    def __init__(self, data = 0):
        self.data = data
        self.left = None
        self.right = None
     
# Iterative function to do Preorder traversal of the tree
def preorderIterative(root):
 
    if (root == None):
        return
 
    st = []
 
    # start from root node (set current node to root node)
    curr = root
 
    # run till stack is not empty or current is
    # not NULL
    while (len(st) or curr != None):
     
        # Print left children while exist
        # and keep appending right into the
        # stack.
        while (curr != None):
         
            print(curr.data, end = " ")
 
            if (curr.right != None):
                st.append(curr.right)
 
            curr = curr.left
         
        # We reach when curr is NULL, so We
        # take out a right child from stack
        if (len(st) > 0):
            curr = st[-1]
            st.pop()
             
# Driver Code
 
root = Node(10)
root.left = Node(20)
root.right = Node(30)
root.left.left = Node(40)
root.left.left.left = Node(70)
root.left.right = Node(50)
root.right.left = Node(60)
root.left.left.right = Node(80)
 
preorderIterative(root)
 
# This code is contributed by Arnab Kundu

Time complexity: linear
Space complexity: logn
# Python program for diagonal
# traversal of Binary Tree
 
# A binary tree node
class Node:
 
    # Constructor to create a
    # new binary tree node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
 
""" root - root of the binary tree
   d -  distance of current line from rightmost
        -topmost slope.
   diagonalPrint - multimap to store Diagonal
                   elements (Passed by Reference) """
def diagonalPrintUtil(root, d, diagonalPrintMap):
     
    # Base Case
    if root is None:
        return
 
    # Store all nodes of same line
    # together as a vector
    try :
        diagonalPrintMap[d].append(root.data)
    except KeyError:
        diagonalPrintMap[d] = [root.data]
 
    # Increase the vertical distance
    # if left child
    diagonalPrintUtil(root.left,
                        d+1, diagonalPrintMap)
     
    # Vertical distance remains
    # same for right child
    diagonalPrintUtil(root.right,
                           d, diagonalPrintMap)
 
 
 
# Print diagonal traversal of given binary tree
def diagonalPrint(root):
 
    # Create a dict to store diagonal elements
    diagonalPrintMap = dict()
     
    # Find the diagonal traversal
    diagonalPrintUtil(root, 0, diagonalPrintMap)
 
    print ("Diagonal Traversal of binary tree : ")
    for i in diagonalPrintMap:
        for j in diagonalPrintMap[i]:
            print (j,end=" ")
        print()
 
 
# Driver Program
root = Node(8)
root.left = Node(3)
root.right = Node(10)
root.left.left = Node(1)
root.left.right = Node(6)
root.right.right = Node(14)
root.right.right.left = Node(13)
root.left.right.left = Node(4)
root.left.right.right = Node(7)
 
diagonalPrint(root)
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: nlogn
Space complexity: linear
from collections import deque
 
# A binary tree node
 
 
class Node:
 
    # Constructor to create a
    # new binary tree node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
 
def diagonal(root):
    out = []
    node = root
 
    # queue to store left nodes
    left_q = deque()
    while node:
 
        # append data to output array
        out.append(node.data)
 
        # if left available add it to the queue
        if node.left:
            left_q.appendleft(node.left)
 
        # if right is available change the node
        if node.right:
            node = node.right
        else:
 
            # else pop the left_q
            if len(left_q) >= 1:
                node = left_q.pop()
            else:
                node = None
    return out
 
 
# Driver Code
root = Node(8)
root.left = Node(3)
root.right = Node(10)
root.left.left = Node(1)
root.left.right = Node(6)
root.right.right = Node(14)
root.right.right.left = Node(13)
root.left.right.left = Node(4)
root.left.right.right = Node(7)
 
print(diagonal(root))

Time complexity: nlogn
Space complexity: linear
# Python Program to print diagonal traversal using queue
 
# Tree Node
class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None
 
 
def diagonalPrint(root):
    if root is None:
        return
 
    q = []
    q.append(root)
 
    while len(q) > 0:
        size = len(q)
        answer = []
 
        while size > 0:
            temp = q[0]
            q.pop(0)
 
            # traversing each component;
            while temp is not None:
                answer.append(temp.data)
 
                if temp.left is not None:
                    q.append(temp.left)
 
                temp = temp.right
 
            size -= 1
 
        result.append(answer)
 
 
if __name__ == '__main__':
    root = Node(8)
    root.left = Node(3)
    root.right = Node(10)
    root.left.left = Node(1)
    root.left.right = Node(6)
    root.right.right = Node(14)
    root.right.right.left = Node(13)
    root.left.right.left = Node(4)
    root.left.right.right = Node(7)
 
    result = []
 
    diagonalPrint(root)
 
    for i in range(len(result)):
        for j in range(len(result[i])):
            print(result[i][j], end=" ")
        print()
 
# This code is contributed by Tapesh(tapeshdua420)

Time complexity: linear
Space complexity: linear
# Python3 program to print the diagonal traversal of binary tree
 
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
#root node
root=Node(0)
 
# function to print in diagonal order
def traverse():
    # if the tree is empty, do not have to print
    # anything
    if root is None:
        return
 
    # if root is not empty, point curr node to the
    # root node
    curr = root
 
    # Maintain a queue to store left child
    q = []
 
    # continue till the queue is empty and curr is null
    while(len(q)!=0 or  curr != None):
            # if curr is not null
            # 1. print the data of the curr node
            # 2. if left child is present, add it to the queue
            # 3. Move curr pointer to the right
        if(curr != None):
            print(curr.data,end=" ")
 
            if(curr.left != None):
                q.append(curr.left)
            curr = curr.right
            # if curr is null, remove a node from the queue
            # and point it to curr node
        else:
            curr = q.pop(0)
 
 
# Driver Code
root = Node(8)
root.left = Node(3)
root.right = Node(10)
root.left.left = Node(1)
root.left.right = Node(6)
root.right.right = Node(14)
root.right.right.left = Node(13)
root.left.right.left = Node(4)
root.left.right.right = Node(7)
traverse()
 
# This code is contributed by Abhijeet Kumar(abhijeet19403)

Time complexity: linear
Space complexity: linear
# Python3 program to find density
# of a binary tree
 
# A binary tree node
# Helper function to allocates a new node
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
         
# Function to compute height and
# size of a binary tree
def heighAndSize(node, size):
 
    if (node == None) :
        return 0
 
    # compute height of each subtree
    l = heighAndSize(node.left, size)
    r = heighAndSize(node.right, size)
 
    #increase size by 1
    size[0] += 1
 
    # return larger of the two
    return l + 1 if(l > r) else r + 1
 
# function to calculate density
# of a binary tree
def density(root):
 
    if (root == None) :
        return 0
 
    size = [0] # To store size
 
    # Finds height and size
    _height = heighAndSize(root, size)
 
    return size[0] / _height
 
# Driver Code
if __name__ == '__main__':
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
 
    print("Density of given binary tree is ",
                               density(root))
 
# This code is contributed
# by SHUBHAMSINGH10

Time complexity: linear
Space complexity: logn
#Python program to find height of full binary tree
# using preorder
     
# function to return max of left subtree height
# or right subtree height
def findDepthRec(tree, n, index) :
 
    if (index[0] >= n or tree[index[0]] == 'l'):
        return 0
 
    # calc height of left subtree (In preorder
    # left subtree is processed before right)
    index[0] += 1
    left = findDepthRec(tree, n, index)
 
    # calc height of right subtree
    index[0] += 1
    right = findDepthRec(tree, n, index)
    return (max(left, right) + 1)
 
# Wrapper over findDepthRec()
def findDepth(tree, n) :
 
    index = [0]
    return findDepthRec(tree, n, index)
 
         
# Driver program to test above functions
if __name__ == '__main__':
    tree= "nlnnlll"
    n = len(tree)
 
    print(findDepth(tree, n))
 
# This code is contributed by SHUBHAMSINGH10

Time complexity: linear
Space complexity: constant
# Python code to modify binary tree for
# traversal using only right pointer
 
class newNode():
 
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
         
         
# Function to modify tree
def modifytree(root):
 
    right = root.right
    rightMost = root
 
    # if the left tree exists
    if (root.left):
 
        # get the right-most of the
        # original left subtree
        rightMost = modifytree(root.left)
 
        # set root right to left subtree
        root.right = root.left
        root.left = None
     
 
    # if the right subtree does
    # not exists we are done!
    if (not right):
        return rightMost
 
    # set right pointer of right-most
    # of the original left subtree
    rightMost.right = right
 
    # modify the rightsubtree
    rightMost = modifytree(right)
    return rightMost
 
 
# printing using right pointer only
def printpre(root):
 
    while (root != None):
        print(root.data,end=" ")
        root = root.right
         
# Driver code
if __name__ == '__main__':
    """ Constructed binary tree is
    10
        / \
    8 2
    / \
    3 5     """
    root = newNode(10)
    root.left = newNode(8)
    root.right = newNode(2)
    root.left.left = newNode(3)
    root.left.right = newNode(5)
 
    modifytree(root)
    printpre(root)
 
# This code is contributed by SHUBHAMSINGH10

Time complexity: linear
Space complexity: linear
# Python code to modify binary tree for
# traversal using only right pointer
 
# A binary tree node has data,
# left child and right child
class newNode():
 
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# An iterative process to set the right
# pointer of Binary tree
def modifytree( root):
     
    # Base Case
    if (root == None):
        return
         
    # Create an empty stack and append root to it
    nodeStack = []
    nodeStack.append(root)
     
    ''' Pop all items one by one.
    Do following for every popped item
    a) print
    b) append its right child
    c) append its left child
    Note that right child is appended first
    so that left is processed first '''
    pre = None
    while (len(nodeStack)):
         
        # Pop the top item from stack
        node = nodeStack[-1]
        nodeStack.pop()
         
        # append right and left children of
        # the popped node to stack
        if (node.right):
            nodeStack.append(node.right)
        if (node.left):
            nodeStack.append(node.left)
             
        # check if some previous node exists
        if (pre != None):
             
            # set the right pointer of
            # previous node to current
            pre.right = node
             
        # set previous node as current node
        pre = node
         
# printing using right pointer only
def printpre( root):
    while (root != None):
        print(root.data, end = " ")
        root = root.right
     
# Driver code
 
''' Constructed binary tree is
        10
    / \
    8     2
/ \    
3     5
'''
root = newNode(10)
root.left = newNode(8)
root.right = newNode(2)
root.left.left = newNode(3)
root.left.right = newNode(5)
 
modifytree(root)
printpre(root)
 
# This code is contributed by SHUBHAMSINGH10

Time complexity: linear
Space complexity: linear
# Python program to construct tree using inorder and
# preorder traversals
 
# 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
 
"""Recursive function to construct binary of size len from
   Inorder traversal in[] and Preorder traversal pre[].  Initial values
   of inStrt and inEnd should be 0 and len -1.  The function doesn't
   do any error checking for cases where inorder and preorder
   do not form a tree """
def buildTree(inOrder, preOrder, inStrt, inEnd):
     
    if (inStrt > inEnd):
        return None
 
    # Pick current node from Preorder traversal using
    # preIndex and increment preIndex
    tNode = Node(preOrder[buildTree.preIndex])
    buildTree.preIndex += 1
 
    # If this node has no children then return
    if inStrt == inEnd :
        return tNode
 
    # Else find the index of this node in Inorder traversal
    inIndex = search(inOrder, inStrt, inEnd, tNode.data)
     
    # Using index in Inorder Traversal, construct left
    # and right subtrees
    tNode.left = buildTree(inOrder, preOrder, inStrt, inIndex-1)
    tNode.right = buildTree(inOrder, preOrder, inIndex + 1, inEnd)
 
    return tNode
 
# UTILITY FUNCTIONS
# Function to find index of value in arr[start...end]
# The function assumes that value is present in inOrder[]
 
def search(arr, start, end, value):
    for i in range(start, end + 1):
        if arr[i] == value:
            return i
 
def printInorder(node):
    if node is None:
        return
     
    # first recur on left child
    printInorder(node.left)
     
    # then print the data of node
    print (node.data,end=' ')
 
    # now recur on right child
    printInorder(node.right)
     
# Driver program to test above function
inOrder = ['D', 'B', 'E', 'A', 'F', 'C']
preOrder = ['A', 'B', 'D', 'E', 'C', 'F']
# Static variable preIndex
buildTree.preIndex = 0
root = buildTree(inOrder, preOrder, 0, len(inOrder)-1)
 
# Let us test the build tree by printing Inorder traversal
print ("Inorder traversal of the constructed tree is")
printInorder(root)
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: quadratic
Space complexity: linear
# Python3 program to construct tree using inorder
# and preorder traversals
 
# A binary tree node has data, pointer to left child
# and a pointer to right child
class Node:
     
    def __init__(self, x):
         
        self.data = x
        self.left = None
        self.right = None
 
# Recursive function to construct binary of size
# len from Inorder traversal in[] and Preorder traversal
# pre[]. Initial values of inStrt and inEnd should be
# 0 and len -1. The function doesn't do any error
# checking for cases where inorder and preorder
# do not form a tree
def buildTree(inn, pre, inStrt, inEnd):
     
    global preIndex, mp
 
    if (inStrt > inEnd):
        return None
 
    # Pick current node from Preorder traversal
    # using preIndex and increment preIndex
    curr = pre[preIndex]
    preIndex += 1
    tNode = Node(curr)
 
    # If this node has no children then return
    if (inStrt == inEnd):
        return tNode
 
    # Else find the index of this
    # node in Inorder traversal
    inIndex = mp[curr]
 
    # Using index in Inorder traversal,
    # construct left and right subtress
    tNode.left = buildTree(inn, pre, inStrt,
                           inIndex - 1)
    tNode.right = buildTree(inn, pre, inIndex + 1,
                            inEnd)
 
    return tNode
 
# This function mainly creates an
# unordered_map, then calls buildTree()
def buldTreeWrap(inn, pre, lenn):
     
    global mp
     
    # Store indexes of all items so that we
    # we can quickly find later
    # unordered_map<char, int> mp;
    for i in range(lenn):
        mp[inn[i]] = i
 
    return buildTree(inn, pre, 0, lenn - 1)
 
# This function is here just to test buildTree()
def printInorder(node):
 
    if (node == None):
        return
         
    printInorder(node.left)
    print(node.data, end = " ")
    printInorder(node.right)
 
# Driver code
if __name__ == '__main__':
     
    mp = {}
    preIndex = 0
 
    inn = [ 'D', 'B', 'E', 'A', 'F', 'C' ]
    pre = [ 'A', 'B', 'D', 'E', 'C', 'F' ]
    lenn = len(inn)
 
    root = buldTreeWrap(inn, pre,lenn)
 
    # Let us test the built tree by printing
    # Inorder traversal
    print("Inorder traversal of "
          "the constructed tree is")
     
    printInorder(root)
 
# This code is contributed by mohit kumar 29

Time complexity: linear
Space complexity: linear