Banana-Leopard/TASTY huggingface dataset:
# Python3 program to construct a tree using
# inorder and preorder traversal
class TreeNode:
     
    def __init__(self, x):     
        self.val = x
        self.left = None
        self.right = None
 
s = set()
st = []
 
# Function to build tree using given traversal
def buildTree(preorder, inorder, n):
    root = None;
     
    pre = 0
    in_t = 0
     
    while pre < n:
        node = None;
         
        while True:   
            node = TreeNode(preorder[pre])
             
            if (root == None):           
                root = node;
              
            if (len(st) > 0):       
                if (st[-1] in s):               
                    s.discard(st[-1]);
                    st[-1].right = node;
                    st.pop();
             
                else:               
                    st[-1].left = node;
                         
            st.append(node);
             
            if pre>=n or preorder[pre] == inorder[in_t]:
                pre += 1
                break
            pre += 1
             
        node = None;
         
        while (len(st) > 0 and in_t < n and st[-1].val == inorder[in_t]):       
            node = st[-1];
            st.pop();
            in_t += 1
     
 
        if (node != None):       
            s.add(node);
            st.append(node);
 
    return root;
 
# Function to print tree in_t Inorder
def printInorder( node):
 
    if (node == None):
        return;
 
    ''' first recur on left child '''
    printInorder(node.left);
 
    ''' then print data of node '''
    print(node.val, end=" ");
 
    ''' now recur on right child '''
    printInorder(node.right);
 
# Driver code
if __name__=='__main__':
     
    in_t = [ 9, 8, 4, 2, 10, 5, 10, 1, 6, 3, 13, 12, 7 ]
    pre = [ 1, 2, 4, 8, 9, 5, 10, 10, 3, 6, 7, 12, 13 ]
    l = len(in_t)
 
    root = buildTree(pre, in_t, l);
 
    printInorder(root);
     
    # This code is contributed by rutvik_56.

Time complexity: linear
Space complexity: linear
# Python program to construct tree using
# inorder and level order traversals
 
# A binary tree node
 
 
class Node:
 
    # Constructor to create a new node
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None
 
 
"""Recursive function to construct binary tree of size n from
Inorder traversal ino[] and Level Order traversal level[].
The function doesn't do any error checking for cases
where inorder and levelorder do not form a tree """
 
 
def buildTree(level, ino):
 
    # If ino array is not empty
    if ino:
 
        # Check if that element exist in level order
        for i in range(0, len(level)):
 
            if level[i] in ino:
 
                # Create a new node with
                # the matched element
                node = Node(level[i])
 
                # Get the index of the matched element
                # in level order array
                io_index = ino.index(level[i])
                break
 
        # Construct left and right subtree
        node.left = buildTree(level, ino[0:io_index])
        node.right = buildTree(level, ino[io_index + 1:len(ino)])
        return node
 
    else:
        return None
 
 
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 code
 
 
levelorder = [20, 8, 22, 4, 12, 10, 14]
inorder = [4, 8, 10, 12, 14, 20, 22]
 
ino_len = len(inorder)
root = buildTree(levelorder, inorder)
 
# 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 'Vaibhav Kumar'

Time complexity: cubic
Space complexity: linear
# Python program to create a Complete Binary Tree from
# its linked list representation
 
# Linked List node
class ListNode:
 
        # Constructor to create a new node
        def __init__(self, data):
            self.data = data
            self.next = None
 
# Binary Tree Node structure
class BinaryTreeNode:
 
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Class to convert the linked list to Binary Tree
class Conversion:
 
    # Constructor for storing head of linked list
    # and root for the Binary Tree
    def __init__(self, data = None):
        self.head = None
        self.root = None
 
    def push(self, new_data):
 
        # Creating a new linked list node and storing data
        new_node = ListNode(new_data)
 
        # Make next of new node as head
        new_node.next = self.head
 
        # Move the head to point to new node
        self.head = new_node
 
    def convertList2Binary(self):
 
        # Queue to store the parent nodes
        q = []
 
        # Base Case
        if self.head is None:
            self.root = None
            return
 
        # 1.) The first node is always the root node,
        # and add it to the queue
        self.root = BinaryTreeNode(self.head.data)
        q.append(self.root)
 
        # Advance the pointer to the next node
        self.head = self.head.next
 
        # Until the end of linked list is reached, do:
        while(self.head):
 
            # 2.a) Take the parent node from the q and
            # and remove it from q
            parent = q.pop(0) # Front of queue
 
            # 2.c) Take next two nodes from the linked list.
            # We will add them as children of the current
            # parent node in step 2.b.
            # Push them into the queue so that they will be
            # parent to the future node
            leftChild= None
            rightChild = None
 
            leftChild = BinaryTreeNode(self.head.data)
            q.append(leftChild)
            self.head = self.head.next
            if(self.head):
                rightChild = BinaryTreeNode(self.head.data)
                q.append(rightChild)
                self.head = self.head.next
 
            #2.b) Assign the left and right children of parent
            parent.left = leftChild
            parent.right = rightChild
 
    def inorderTraversal(self, root):
        if(root):
            self.inorderTraversal(root.left)
            print (root.data,end=" ")
            self.inorderTraversal(root.right)
 
# Driver Program to test above function
 
# Object of conversion class
conv = Conversion()
conv.push(36)
conv.push(30)
conv.push(25)
conv.push(15)
conv.push(12)
conv.push(10)
 
conv.convertList2Binary()
 
print ("Inorder Traversal of the constructed Binary Tree is:")
conv.inorderTraversal(conv.root)
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: linear
Space complexity: np
# Python3 program to construct binary 
# tree from given array in level 
# order fashion Tree Node 
  
# Helper function that allocates a 
#new node
class newNode:
    def __init__(self, data):
        self.data = data 
        self.left = self.right = None
  
# Function to insert nodes in level order 
def insertLevelOrder(arr, i, n):
    root = None
    # Base case for recursion 
    if i < n:
        root = newNode(arr[i]) 
  
        # insert left child 
        root.left = insertLevelOrder(arr, 2 * i + 1, n)
  
        # insert right child 
        root.right = insertLevelOrder(arr, 2 * i + 2, n)
          
    return root
  
# Function to print tree nodes in 
# InOrder fashion 
def inOrder(root):
    if root != None:
        inOrder(root.left) 
        print(root.data,end=" ") 
        inOrder(root.right)
  
# Driver Code
if __name__ == '__main__':
    arr = [1, 2, 3, 4, 5, 6, 6, 6, 6]
    n = len(arr)
    root = None
    root = insertLevelOrder(arr, 0, n) 
    inOrder(root)
      
# This code is contributed by PranchalK and Improved by Thangaraj

Time complexity: linear
Space complexity: linear
# Python3 program for construction of
# full binary tree
 
# A binary tree node has data, pointer
# to left child and a pointer to right child
class Node:
     
    def __init__(self, data):
         
        self.data = data
        self.left = None
        self.right = None
 
# A recursive function to construct
# Full from pre[] and post[].
# preIndex is used to keep track
# of index in pre[]. l is low index
# and h is high index for the
# current subarray in post[]
def constructTreeUtil(pre: list, post: list,
                        l: int, h: int,
                     size: int) -> Node:
    global preIndex
     
    # Base case
    if (preIndex >= size or l > h):
        return None
 
    # The first node in preorder traversal
    # is root. So take the node at preIndex
    # from preorder and make it root, and
    # increment preIndex
    root = Node(pre[preIndex])
    preIndex += 1
 
    # If the current subarray has only
    # one element, no need to recur
    if (l == h or preIndex >= size):
        return root
 
    # Search the next element
    # of pre[] in post[]
    i = l
    while i <= h:
        if (pre[preIndex] == post[i]):
            break
         
        i += 1
 
    # Use the index of element
    # found in postorder to divide
    # postorder array in two parts.
    # Left subtree and right subtree
    if (i <= h):
        root.left = constructTreeUtil(pre, post,
                                      l, i, size)
        root.right = constructTreeUtil(pre, post,
                                       i + 1, h-1,
                                       size)
 
    return root
 
# The main function to construct
# Full Binary Tree from given
# preorder and postorder traversals.
# This function mainly uses constructTreeUtil()
def constructTree(pre: list,
                 post: list,
                 size: int) -> Node:
                      
    global preIndex
     
    return constructTreeUtil(pre, post, 0,
                             size - 1, size)
 
# A utility function to print
# inorder traversal of a Binary Tree
def printInorder(node: Node) -> None:
 
    if (node is None):
        return
     
    printInorder(node.left)
    print(node.data, end = " ")
     
    printInorder(node.right)
 
# Driver code
if __name__ == "__main__":
     
    pre = [ 1, 2, 4, 8, 9, 5, 3, 6, 7 ]
    post = [ 8, 9, 4, 5, 2, 6, 7, 3, 1 ]
    size = len(pre)
 
    preIndex = 0
 
    root = constructTree(pre, post, size)
 
    print("Inorder traversal of "
          "the constructed tree: ")
           
    printInorder(root)
 
# This code is contributed by sanjeev2552

Time complexity: constant
Space complexity: logn
# Python3 program to construct full binary
# tree using its preorder traversal and
# preorder traversal of its mirror tree
 
# Utility function to create a new tree node
class newNode:
    def __init__(self,data):
        self.data = data
        self.left = self.right = None
 
# A utility function to print inorder
# traversal of a Binary Tree
def printInorder(node):
    if (node == None) :
        return
    printInorder(node.left)
    print(node.data, end = " ")
    printInorder(node.right)
 
# A recursive function to construct Full 
# binary tree from pre[] and preM[].
# preIndex is used to keep track of index
# in pre[]. l is low index and h is high
# index for the current subarray in preM[]
def constructBinaryTreeUtil(pre, preM, preIndex,
                                    l, h, size):
    # Base case
    if (preIndex >= size or l > h) :
        return None , preIndex
 
    # The first node in preorder traversal 
    # is root. So take the node at preIndex
    # from preorder and make it root, and
    # increment preIndex
    root = newNode(pre[preIndex])
    preIndex += 1
 
    # If the current subarray has only
    # one element, no need to recur
    if (l == h):
        return root, preIndex
 
    # Search the next element of
    # pre[] in preM[]
    i = 0
    for i in range(l, h + 1):
        if (pre[preIndex] == preM[i]):
                break
 
    # construct left and right subtrees
    # recursively
    if (i <= h):
 
        root.left, preIndex = constructBinaryTreeUtil(pre, preM, preIndex,
                                                               i, h, size)
        root.right, preIndex = constructBinaryTreeUtil(pre, preM, preIndex,
                                                       l + 1, i - 1, size)
 
    # return root
    return root, preIndex
 
# function to construct full binary tree
# using its preorder traversal and preorder
# traversal of its mirror tree
def constructBinaryTree(root, pre, preMirror, size):
 
    preIndex = 0
    preMIndex = 0
 
    root, x = constructBinaryTreeUtil(pre, preMirror, preIndex,
                                             0, size - 1, size)
 
    Print Inorder(root)
 
# Driver code
if __name__ =="__main__":
 
    preOrder = [1, 2, 4, 5, 3, 6, 7]
    preOrderMirror = [1, 3, 7, 6, 2, 5, 4]
 
    size = 7
    root = newNode(0)
 
    constructBinaryTree(root, preOrder,
                        preOrderMirror, size)
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)

Time complexity: quadratic
Space complexity: linear
# key structure to store a binary tree node
class Node:
    def __init__(self, key, left = None, right = None):
        self.key = key
        self.left = left
        self.right = right
 
# Utility function to print binary tree nodes in-order fashion
def inorder(node):
    if node:
        inorder(node.left)
        print(node.key, end = ' ')
        inorder(node.right)
 
# Function to construct a binary tree
# from specified ancestor matrix
def constructBT(mat):
   
    # get number of rows in the matrix
    N = len(mat)
 
    # create an empty multi-dict
    dict = {}
 
    # Use sum as key and row numbers as values in the multi-dict
    for i in range(N):
 
        # find the sum of the current row
        total = sum(mat[i])
 
        # insert the sum and row number into the dict
        dict.setdefault(total, []).append(i)
 
    # node[i] will store node for i in constructed tree
    node = [Node(-1)] * N
    last = 0
 
    # the value of parent[i] is true if parent is set for i'th node
    parent = [False] * N
 
    # Traverse the dictionary in sorted order (default behavior)
    for key in dict.keys():
        for row in dict.get(key):
            last = row
             
            # create a new node
            node[row] = Node(row)
 
            # if leaf node, do nothing
            if key == 0:
                continue
 
            # traverse row
            for i in range(N):
               
                # do if parent is not set and ancestor exits
                if not parent[i] and mat[row][i] == 1:
                   
                    # check for the unoccupied node
                    if node[row].left is None:
                        node[row].left = node[i]
                    else:
                        node[row].right = node[i]
 
                    # set parent for i'th node
                    parent[i] = True
 
    # last processed node is the root
    return node[last]
 
# Construct a Binary Tree from Ancestor Matrix
if __name__ == '__main__':
 
    mat = [[0, 0, 0, 0, 0, 0],
        [1, 0, 0, 0, 1, 0],
        [0, 0, 0, 1, 0, 0],
        [0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0],
        [1, 1, 1, 1, 0, 0]]
 
    root = constructBT(mat)
    inorder(root)
 
# This code is contributed by Priyadarshini Kumari

Time complexity: quadratic
Space complexity: quadratic
# Python3 program to construct ancestor
# matrix for given tree.
 
class newnode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
         
# anc[] stores all ancestors of current node.
# This function fills ancestors for all nodes.
# It also returns size of tree. Size of tree 
# is used to print ancestor matrix.
def ancestorMatrixRec(root, anc):
    global mat, MAX
     
    # base case
    if root == None:
        return 0
 
    # Update all ancestors of current node
    data = root.data
    for i in range(len(anc)):
        mat[anc[i]][data] = 1
 
    # Push data to list of ancestors
    anc.append(data)
 
    # Traverse left and right subtrees
    l = ancestorMatrixRec(root.left, anc)
    r = ancestorMatrixRec(root.right, anc)
 
    # Remove data from list the list of ancestors
    # as all descendants of it are processed now.
    anc.pop(-1)
 
    return l + r + 1
 
# This function mainly calls ancestorMatrixRec()
def ancestorMatrix(root):
     
    # Create an empty ancestor array
    anc = []
 
    # Fill ancestor matrix and find
    # size of tree.
    n = ancestorMatrixRec(root, anc)
 
    # Print the filled values
    for i in range(n):
        for j in range(n):
            print(mat[i][j], end = " ")
        print()
 
# Driver Code
MAX = 100
mat = [[0] * MAX for i in range(MAX)]
 
# Construct the following binary tree
#         5
#         / \
#     1     2
#     / \ /
#     0 4 3
root = newnode(5)
root.left = newnode(1)
root.right = newnode(2)
root.left.left = newnode(0)
root.left.right = newnode(4)
root.right.left = newnode(3)
 
ancestorMatrix(root)
 
# This code is contributed by PranchalK

Time complexity: quadratic
Space complexity: quadratic
# Python3 program to construct ancestor
# matrix for given tree.
size = 6
  
M = [[0 for j in range(size)]
        for i in range(size)]
 
# A binary tree node
class Node:
     
    def __init__(self, data):
         
        self.left = None
        self.right = None
        self.data = data
         
# Helper function to create a new node
def newnode(data):
 
    temp = Node(data)
     
    return temp
 
def printMatrix():
     
    for i in range(size):
        for j in range(size):
            print(M[i][j], end = ' ')
         
        print()    
  
# First PreOrder Traversal
def MatrixUtil(root, index):
     
    if (root == None):
        return
      
    preData = root.data
              
    # Since there is no ancestor for
    # root node, so we doesn't assign
    # it's value as 1           
    if (index == -1):
        index = root.data
    else:
        M[index][preData] = 1   
      
    MatrixUtil(root.left, preData)
    MatrixUtil(root.right, preData)
 
def Matrix(root):
     
    # Call Func MatrixUtil
    MatrixUtil(root, -1)
      
    # Applying Transitive Closure
    # for the given Matrix
    for i in range(size):
        for j in range(size):
            for k in range(size):
                M[j][k] = (M[j][k] or
                          (M[j][i] and
                           M[i][k]))
      
    # Printing Matrix
    printMatrix()
  
# Driver code
if __name__=="__main__":
     
    root = newnode(5)
    root.left = newnode(1)
    root.right = newnode(2)
    root.left.left = newnode(0)
    root.left.right = newnode(4)
    root.right.left = newnode(3)
  
    Matrix(root)
      
# This code is contributed by rutvik_56

Time complexity: quadratic
Space complexity: quadratic
# Python3 program to construct tree from
# inorder traversal
 
# Helper class that allocates a new node
# with the given data and None left and
# right pointers.
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Prototypes of a utility function to get
# the maximum value in inorder[start..end]
 
# Recursive function to construct binary of
# size len from Inorder traversal inorder[].
# Initial values of start and end should be
# 0 and len -1.
def buildTree (inorder, start, end):
    if start > end:
        return None
 
    # Find index of the maximum element
    # from Binary Tree
    i = Max (inorder, start, end)
 
    # Pick the maximum value and make it root
    root = newNode(inorder[i])
 
    # If this is the only element in
    # inorder[start..end], then return it
    if start == end:
        return root
 
    # Using index in Inorder traversal,
    # construct left and right subtress
    root.left = buildTree (inorder, start, i - 1)
    root.right = buildTree (inorder, i + 1, end)
 
    return root
 
# UTILITY FUNCTIONS
 
# Function to find index of the maximum
# value in arr[start...end]
def Max(arr, strt, end):
    i, Max = 0, arr[strt]
    maxind = strt
    for i in range(strt + 1, end + 1):
        if arr[i] > Max:
            Max = arr[i]
            maxind = i
    return maxind
 
# This function is here just to test buildTree()
def printInorder (node):
    if node == 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 Code
if __name__ == '__main__':
     
    # Assume that inorder traversal of
    # following tree is given
    #     40
    # / \
    # 10     30
    # /         \
    #5         28
 
    inorder = [5, 10, 40, 30, 28]
    Len = len(inorder)
    root = buildTree(inorder, 0, Len - 1)
 
    # 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 PranchalK

Time complexity: quadratic
Space complexity: linear
# Python3 program to construct tree using
# inorder and postorder traversals
 
# Helper function that allocates
# a new node
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
 
# Recursive function to construct binary
# of size n from Inorder traversal in[]
# and Postorder traversal post[]. Initial
# values of inStrt and inEnd should be
# 0 and n -1. The function doesn't do any
# error checking for cases where inorder
# and postorder do not form a tree
def buildUtil(In, post, inStrt, inEnd, pIndex):
     
    # Base case
    if (inStrt > inEnd):
        return None
 
    # Pick current node from Postorder traversal
    # using postIndex and decrement postIndex
    node = newNode(post[pIndex[0]])
    pIndex[0] -= 1
 
    # If this node has no children
    # then return
    if (inStrt == inEnd):
        return node
 
    # Else find the index of this node
    # in Inorder traversal
    iIndex = search(In, inStrt, inEnd, node.data)
 
    # Using index in Inorder traversal,
    # construct left and right subtress
    node.right = buildUtil(In, post, iIndex + 1,
                                  inEnd, pIndex)
    node.left = buildUtil(In, post, inStrt,
                        iIndex - 1, pIndex)
 
    return node
 
# This function mainly initializes index
# of root and calls buildUtil()
def buildTree(In, post, n):
    pIndex = [n - 1]
    return buildUtil(In, post, 0, n - 1, pIndex)
 
# Function to find index of value in
# arr[start...end]. The function assumes
# that value is postsent in in[]
def search(arr, strt, end, value):
    i = 0
    for i in range(strt, end + 1):
        if (arr[i] == value):
            break
    return i
 
# This function is here just to test
def preOrder(node):
    if node == None:
        return
    print(node.data,end=" ")
    preOrder(node.left)
    preOrder(node.right)
 
# Driver code
if __name__ == '__main__':
    In = [4, 8, 2, 5, 1, 6, 3, 7]
    post = [8, 4, 5, 2, 6, 7, 3, 1]
    n = len(In)
 
    root = buildTree(In, post, n)
 
    print("Preorder of the constructed tree :")
    preOrder(root)
 
# This code is contributed by PranchalK

Time complexity: quadratic
Space complexity: linear