Banana-Leopard/TASTY huggingface dataset:
# Python3 implementation to convert the
# given BST to Min Heap
 
# structure of a node of BST
 
 
class Node:
 
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# function for the inorder traversal
# of the tree so as to store the node
# values in 'arr' in sorted order
 
 
def inorderTraversal(root, arr):
    if root == None:
        return
 
    # first recur on left subtree
    inorderTraversal(root.left, arr)
 
    # then copy the data of the node
    arr.append(root.data)
 
    # now recur for right subtree
    inorderTraversal(root.right, arr)
 
# function to convert the given
# BST to MIN HEAP performs preorder
# traversal of the tree
 
 
def BSTToMinHeap(root, arr, i):
    if root == None:
        return
 
    # first copy data at index 'i' of
    # 'arr' to the node
    i[0] += 1
    root.data = arr[i[0]]
 
    # then recur on left subtree
    BSTToMinHeap(root.left, arr, i)
 
    # now recur on right subtree
    BSTToMinHeap(root.right, arr, i)
 
# utility function to convert the
# given BST to MIN HEAP
 
 
def convertToMinHeapUtil(root):
 
    # vector to store the data of
    # all the nodes of the BST
    arr = []
    i = [-1]
 
    # inorder traversal to populate 'arr'
    inorderTraversal(root, arr)
 
    # BST to MIN HEAP conversion
    BSTToMinHeap(root, arr, i)
 
# function for the preorder traversal
# of the tree
 
 
def preorderTraversal(root):
    if root == None:
        return
 
    # first print the root's data
    print(root.data, end=" ")
 
    # then recur on left subtree
    preorderTraversal(root.left)
 
    # now recur on right subtree
    preorderTraversal(root.right)
 
 
# Driver's Code
if __name__ == '__main__':
 
    # BST formation
    root = Node(4)
    root.left = Node(2)
    root.right = Node(6)
    root.left.left = Node(1)
    root.left.right = Node(3)
    root.right.left = Node(5)
    root.right.right = Node(7)
 
    # Function call
    convertToMinHeapUtil(root)
    print("Preorder Traversal:")
    preorderTraversal(root)
 
# This code is contributed
# by PranchalK

Time complexity: linear
Space complexity: linear
# Python3 program to convert a Binary tree
# to BST using sets as containers.
 
# Binary Tree Node
""" A utility function to create a
new BST node """
class newNode:
 
    # Construct to create a newNode
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# function to store the nodes in set
# while doing inorder traversal.
def storeinorderInSet(root, s):
 
    if (not root) :
        return
 
    # visit the left subtree first
    storeinorderInSet(root.left, s)
 
    # insertion takes order of O(logn)
    # for sets
    s.add(root.data)
 
    # visit the right subtree
    storeinorderInSet(root.right, s)
 
# Time complexity = O(nlogn)
 
# function to copy items of set one by one
# to the tree while doing inorder traversal
def setToBST(s, root) :
 
    # base condition
    if (not root):
        return
 
    # first move to the left subtree and
    # update items
    setToBST(s, root.left)
 
    # iterator initially pointing to
    # the beginning of set
    it = next(iter(s))
 
    # copying the item at beginning of
    # set(sorted) to the tree.
    root.data = it
 
    # now erasing the beginning item from set.
    s.remove(it)
 
    # now move to right subtree
    # and update items
    setToBST(s, root.right)
 
# T(n) = O(nlogn) time
 
# Converts Binary tree to BST.
def binaryTreeToBST(root):
 
    s = set()
 
    # populating the set with the tree's
    # inorder traversal data
    storeinorderInSet(root, s)
 
    # now sets are by default sorted as
    # they are implemented using self-
    # balancing BST
 
    # copying items from set to the tree
    # while inorder traversal which makes a BST
    setToBST(s, root)
 
# Time complexity = O(nlogn),
# Auxiliary Space = O(n) for set.
 
# function to do inorder traversal
def inorder(root) :
 
    if (not root) :
        return
    inorder(root.left)
    print(root.data, end = " ")
    inorder(root.right)
 
# Driver Code
if __name__ == '__main__':
 
    root = newNode(5)
    root.left = newNode(7)
    root.right = newNode(9)
    root.right.left = newNode(10)
    root.left.left = newNode(1)
    root.left.right = newNode(6)
    root.right.right = newNode(11)
 
    """ Constructing tree given in
        the above figure
        5
        / \
        7     9
    /\ / \
    1 6 10 11 """
 
    # converting the above Binary tree to BST
    binaryTreeToBST(root)
    print("Inorder traversal of BST is: ")
    inorder(root)
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)

Time complexity: nlogn
Space complexity: linear
# Python program to Merge two BSTs with limited extra space
 
# Structure of a BST Node
class Node:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
 
 
def mergeTwoBST(root1, root2):
    res = []
    s1, s2 = [], []
 
    while root1 or root2 or s1 or s2:
        while root1:
            s1.append(root1)
            root1 = root1.left
 
        while root2:
            s2.append(root2)
            root2 = root2.left
 
        # Step 3 Case 1:-
        if not s2 or (s1 and s1[-1].val <= s2[-1].val):
            root1 = s1[-1]
            del s1[-1]
            res.append(root1.val)
            root1 = root1.right
 
        #  Step 3 case 2 :-
        else:
            root2 = s2[-1]
            del s2[-1]
            res.append(root2.val)
            root2 = root2.right
 
    return res
 
 
# Driver program to test above functions
if __name__ == '__main__':
    root1 = None
    root2 = None
 
    '''
    Let us create the following tree as first tree
             3
            / \
           1   5
    '''
 
    root1 = Node(3)
    root1.left = Node(1)
    root1.right = Node(5)
 
    '''
    Let us create the following tree as second tree
             4
            / \
           2   6
    '''
 
    root2 = Node(4)
    root2.left = Node(2)
    root2.right = Node(6)
 
    ans = mergeTwoBST(root1, root2)
    for x in ans:
        print (x, end=" ")
 
# This code is contributed by Tapesh(tapeshdua420)

Time complexity: linear
Space complexity: logn
# Python3 program to find the node with minimum value in bst
 
# 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
 
 
""" Give a binary search tree and a number,
inserts a new node with the given number in
the correct place in the tree. Returns the new
root pointer which the caller should then use
(the standard trick to avoid using reference
parameters). """
 
 
def insert(node, data):
 
    # 1. If the tree is empty, return a new,
    # single node
    if node is None:
        return (Node(data))
 
    else:
        # 2. Otherwise, recur down the tree
        if data <= node.data:
            node.left = insert(node.left, data)
        else:
            node.right = insert(node.right, data)
 
        # Return the (unchanged) node pointer
        return node
 
 
""" Given a non-empty binary search tree, 
return the minimum data value found in that
tree. Note that the entire tree does not need
to be searched. """
 
 
def minValue(node):
    current = node
 
    # loop down to find the leftmost leaf
    while(current.left is not None):
        current = current.left
 
    return current.data
 
 
# Driver code
if __name__ == '__main__':
  root = None
  root = insert(root, 4)
  insert(root, 2)
  insert(root, 1)
  insert(root, 3)
  insert(root, 6)
  insert(root, 5)
 
  # Function call
  print("\nMinimum value in BST is %d" % (minValue(root)))
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: linear
Space complexity: linear
# Python program for an efficient solution to check if
# a given array can represent Preorder traversal of
# a Binary Search Tree
 
INT_MIN = -2**32
 
def canRepresentBST(pre):
 
    # Create an empty stack
    s = []
 
    # Initialize current root as minimum possible value
    root = INT_MIN
 
    # Traverse given array
    for value in pre:
        #NOTE:value is equal to pre[i] according to the
        #given algo  
     
        # If we find a node who is on the right side
        # and smaller than root, return False
        if value < root :
            return False
     
        # If value(pre[i]) is in right subtree of stack top,
        # Keep removing items smaller than value
        # and make the last removed items as new root
        while(len(s) > 0 and s[-1] < value) :
            root = s.pop()
         
        # At this point either stack is empty or value
        # is smaller than root, push value
        s.append(value)
 
    return True
 
# Driver Program
pre1 = [40 , 30 , 35 , 80 , 100]
print ("true" if canRepresentBST(pre1) == True else "false")
pre2 = [40 , 30 , 35 , 20 ,  80 , 100]
print ("true" if canRepresentBST(pre2) == True else "false")
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: linear
Space complexity: linear
# Python3 program to illustrate if a given array can represent
# a preorder traversal of a BST or not
import sys
 
preIndex = 0
      
# We are actually not building the tree
def buildBST_helper(n, pre, Min, Max):
    global preIndex
    if (preIndex >= n):
        return
 
    if (Min <= pre[preIndex] and pre[preIndex] <= Max):
        # build node
        rootData = pre[preIndex]
        preIndex+=1
 
        # build left subtree
        buildBST_helper(n, pre, Min, rootData)
 
        # build right subtree
        buildBST_helper(n, pre, rootData, Max)
    # else
    # return NULL
 
def canRepresentBST(arr, N):
    global preIndex
    # code here
    Min, Max = sys.maxsize, -sys.maxsize
 
    buildBST_helper(N, arr, Min, Max)
     
    if preIndex == N:
        return True
 
    return False
  
preorder1 = [ 2, 4, 3 ]
"""
        2
        \
         4
        /
       3
 
"""
n1 = len(preorder1)
 
if (not canRepresentBST(preorder1, n1)):
  print("preorder1 can represent BST");
else:
  print("preorder1 can not represent BST  :(")
 
preorder2 = [ 5, 3, 4, 1, 6, 10 ]
n2 = len(preorder2)
"""
                      5
           /     \
         3         1
           \     /  \
           4    6    10
 
"""
if (canRepresentBST(preorder2, n2)):
  print("preorder2 can represent BST")
else:
  print("preorder2 can not represent BST  :(")
 
preorder3 = [ 5, 3, 4, 8, 6, 10 ]
n3 = len(preorder3)
"""
                      5
           /     \
         3         8
           \     /  \
           4    6    10
"""
if (not canRepresentBST(preorder3, n3)):
  print("preorder3 can represent BST")
else:
  print("preorder3 can not represent BST  :(")

Time complexity: linear
Space complexity: logn
# A recursive python program to find LCA of two nodes
# n1 and n2
 
# 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
 
# Function to find LCA of n1 and n2. The function assumes
# that both n1 and n2 are present in BST
 
 
def lca(root, n1, n2):
 
    # Base Case
    if root is None:
        return None
 
    # If both n1 and n2 are smaller than root, then LCA
    # lies in left
    if(root.data > n1 and root.data > n2):
        return lca(root.left, n1, n2)
 
    # If both n1 and n2 are greater than root, then LCA
    # lies in right
    if(root.data < n1 and root.data < n2):
        return lca(root.right, n1, n2)
 
    return root
 
# Driver program to test above function
 
 
# Driver code
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
 
 
# Function calls
n1 = 10
n2 = 14
t = lca(root, n1, n2)
print("LCA of %d and %d is %d" % (n1, n2, t.data))
 
n1 = 14
n2 = 8
t = lca(root, n1, n2)
print("LCA of %d and %d is %d" % (n1, n2, t.data))
 
n1 = 10
n2 = 22
t = lca(root, n1, n2)
print("LCA of %d and %d is %d" % (n1, n2, t.data))
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: constant
Space complexity: logn
# A recursive python program to find LCA of two nodes
# n1 and n2
 
# 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
 
# Function to find LCA of n1 and n2.
# The function assumes that both
#   n1 and n2 are present in BST
 
 
def lca(root, n1, n2):
    while root:
        # If both n1 and n2 are smaller than root,
        # then LCA lies in left
        if root.data > n1 and root.data > n2:
            root = root.left
 
        # If both n1 and n2 are greater than root,
        # then LCA lies in right
        elif root.data < n1 and root.data < n2:
            root = root.right
 
        else:
            break
 
    return root
 
 
# Driver code
if __name__ == '__main__':
  root = Node(20)
  root.left = Node(8)
  root.right = Node(22)
  root.left.left = Node(4)
  root.left.right = Node(12)
  root.left.right.left = Node(10)
  root.left.right.right = Node(14)
 
  # Function calls
  n1 = 10
  n2 = 14
  t = lca(root, n1, n2)
  print("LCA of %d and %d is %d" % (n1, n2, t.data))
 
  n1 = 14
  n2 = 8
  t = lca(root, n1, n2)
  print("LCA of %d and %d is %d" % (n1, n2, t.data))
 
  n1 = 10
  n2 = 22
  t = lca(root, n1, n2)
  print("LCA of %d and %d is %d" % (n1, n2, t.data))
# This Code is Contributed by Sumit Bhardwaj (Timus)

Time complexity: constant
Space complexity: constant
# A Python3 program to check for Identical
# BSTs without building the trees
 
# # The main function that checks if two
# arrays a[] and b[] of size n construct
# same BST. The two values 'min' and 'max'
# decide whether the call is made for left
# subtree or right subtree of a parent
# element. The indexes i1 and i2 are the
# indexes in (a[] and b[]) after which we
# search the left or right child. Initially,
# the call is made for INT_MIN and INT_MAX
# as 'min' and 'max' respectively, because
# root has no parent. i1 and i2 are just
# after the indexes of the parent element in a[] and b[]. */
def isSameBSTUtil(a, b, n, i1, i2, min, max):
 
    # # Search for a value satisfying the
    # constraints of min and max in a[] and
    # b[]. If the parent element is a leaf
    # node then there must be some elements
    # in a[] and b[] satisfying constraint. */
    j, k = i1, i2
    while j < n:
        if (a[j] > min and a[j] < max):
            break;
        j += 1
    while k<n:
        if (b[k] > min and b[k] < max):
            break
        k += 1
 
    # If the parent element is leaf in both arrays */
    if (j == n and k == n):
        return True
 
    # Return false if any of the following is true
        # a) If the parent element is leaf in one array,
        #     but non-leaf in other.
        # b) The elements satisfying constraints are
        #     not same. We either search for left
        #     child or right child of the parent
        #     element (decided by min and max values).
        #     The child found must be same in both arrays */
    if (((j == n) ^ (k == n)) or a[j] != b[k]):
        return False
 
    # Make the current child as parent and
    # recursively check for left and right
    # subtrees of it. Note that we can also
    # pass a[k] in place of a[j] as they
    # are both are same */
    return isSameBSTUtil(a, b, n, j + 1, k + 1, a[j], max) and isSameBSTUtil(a, b, n, j + 1, k + 1, min, a[j]) #Left Subtree
 
# A wrapper over isSameBSTUtil()
def isSameBST(a, b, n):
    return isSameBSTUtil(a, b, n, 0, 0, -10**9, 10**9)
 
# Driver code
if __name__ == '__main__':
    a = [8, 3, 6, 1, 4, 7, 10, 14, 13]
    b = [8, 10, 14, 3, 6, 4, 1, 7, 13]
    n = len(a)
 
    if(isSameBST(a, b, n)):
        print("BSTs are same")
    else:
        print("BSTs not same")
 
# This code is contributed by mohit kumar 29.

Time complexity: quadratic
Space complexity: linear
# Python3 program to find k'th largest 
# element in BST 
  
class Node: 
  
    # Constructor to create a new node 
    def __init__(self, data): 
        self.key = data 
        self.left = None
        self.right = None
          
# A function to find k'th largest 
# element in a given tree. 
def kthLargestUtil(root, k, c):
      
    # Base cases, the second condition 
    # is important to avoid unnecessary
    # recursive calls 
    if root == None or c[0] >= k: 
        return
  
    # Follow reverse inorder traversal 
    # so that the largest element is 
    # visited first 
    kthLargestUtil(root.right, k, c)
  
    # Increment count of visited nodes 
    c[0] += 1
  
    # If c becomes k now, then this is 
    # the k'th largest 
    if c[0] == k:
        print("K'th largest element is", 
                               root.key) 
        return
  
    # Recur for left subtree 
    kthLargestUtil(root.left, k, c)
  
# Function to find k'th largest element 
def kthLargest(root, k):
      
    # Initialize count of nodes
    # visited as 0 
    c = [0]
  
    # Note that c is passed by reference 
    kthLargestUtil(root, k, c)
  
# A utility function to insert a new 
# node with given key in BST */
def insert(node, key): 
      
    # If the tree is empty, 
    # return a new node 
    if node == None:
        return Node(key) 
  
    # Otherwise, recur down the tree 
    if key < node.key: 
        node.left = insert(node.left, key) 
    elif key > node.key:
        node.right = insert(node.right, key) 
  
    # return the (unchanged) node pointer 
    return node
  
# Driver Code
if __name__ == '__main__':
      
    # Let us create following BST 
    #         50 
    #     /     \ 
    #     30     70 
    # / \ / \ 
    # 20 40 60 80 */
    root = None
    root = insert(root, 50)
    insert(root, 30)
    insert(root, 20)
    insert(root, 40)
    insert(root, 70)
    insert(root, 60)
    insert(root, 80)
  
    for k in range(1,8):
        kthLargest(root, k)
          
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: logn
# Python3 code for finding K-th largest
# Node using O(1) extra memory and
# reverse Morris traversal.
 
# helper function to create a new Node
class newNode:
    def __init__(self, data):
        self.data = data
        self.right = self.left = None
 
def KthLargestUsingMorrisTraversal(root, k):
    curr = root
    Klargest = None
 
    # count variable to keep count
    # of visited Nodes
    count = 0
 
    while (curr != None):
         
        # if right child is None
        if (curr.right == None):
 
            # first increment count and
            # check if count = k
            count += 1
            if (count == k):
                Klargest = curr
 
            # otherwise move to the left child
            curr = curr.left
 
        else:
 
            # find inorder successor of
            # current Node
            succ = curr.right
 
            while (succ.left != None and
                   succ.left != curr):
                succ = succ.left
 
            if (succ.left == None):
 
                # set left child of successor
                # to the current Node
                succ.left = curr
 
                # move current to its right
                curr = curr.right
 
            # restoring the tree back to 
            # original binary search tree
            # removing threaded links
            else:
 
                succ.left = None
                count += 1
                if (count == k):
                    Klargest = curr
 
                # move current to its left child
                curr = curr.left
 
    return Klargest
 
# Driver Code
if __name__ == '__main__':
 
    # Constructed binary tree is
    #     4
    #     / \
    # 2     7
    # / \ / \
    # 1 3 6 10
    root = newNode(4)
    root.left = newNode(2)
    root.right = newNode(7)
    root.left.left = newNode(1)
    root.left.right = newNode(3)
    root.right.left = newNode(6)
    root.right.right = newNode(10)
 
    print("Finding K-th largest Node in BST : ",
           KthLargestUsingMorrisTraversal(root, 2).data)
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: constant
# Python 3 program to find k'th
# largest element in BST
 
# A BST node
class Node:
 
    # Constructor to create a new node
    def __init__(self, data):
        self.key = data
        self.left = None
        self.right = None
 
# A function to find
def KSmallestUsingMorris(root, k):
     
    # Count to iterate over elements
    # till we get the kth smallest number
    count = 0
 
    ksmall = -9999999999 # store the Kth smallest
    curr = root # to store the current node
 
    while curr != None:
         
        # Like Morris traversal if current does
        # not have left child rather than
        # printing as we did in inorder, we
        # will just increment the count as the
        # number will be in an increasing order
        if curr.left == None:
            count += 1
 
            # if count is equal to K then we
            # found the kth smallest, so store
            # it in ksmall
            if count == k:
                ksmall = curr.key
 
            # go to current's right child
            curr = curr.right
        else:
             
            # we create links to Inorder Successor
            # and count using these links
            pre = curr.left
            while (pre.right != None and
                   pre.right != curr):
                pre = pre.right
 
            # building links
            if pre.right == None:
                 
                # link made to Inorder Successor
                pre.right = curr
                curr = curr.left
 
            # While breaking the links in so made
            # temporary threaded tree we will check
            # for the K smallest condition
            else:
                 
                # Revert the changes made in if part
                # (break link from the Inorder Successor)
                pre.right = None
 
                count += 1
 
                # If count is equal to K then we
                # found the kth smallest and so
                # store it in ksmall
                if count == k:
                    ksmall = curr.key
         
                curr = curr.right
    return ksmall # return the found value
 
# A utility function to insert a new
# node with given key in BST
def insert(node, key):
     
    # If the tree is empty,
    # return a new node
    if node == None:
        return Node(key)
 
    # Otherwise, recur down the tree
    if key < node.key:
        node.left = insert(node.left, key)
    elif key > node.key:
        node.right = insert(node.right, key)
 
    # return the (unchanged) node pointer
    return node
 
# Driver Code
if __name__ == '__main__':
     
    # Let us create following BST
    #         50
    #       /    \
    #      30    70
    #    /  \  /  \
    #   20 40 60 80
    root = None
    root = insert(root, 50)
    insert(root, 30)
    insert(root, 20)
    insert(root, 40)
    insert(root, 70)
    insert(root, 60)
    insert(root, 80)
 
    for k in range(1,8):
        print(KSmallestUsingMorris(root, k),
                                 end = " ")
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: constant
# Python 3 program to check if a given array
# is sorted or not.
 
# Function that returns true if array is Inorder
# traversal of any Binary Search Tree or not.
def isInorder(arr, n):
     
    # Array has one or no element
    if (n == 0 or n == 1):
        return True
 
    for i in range(1, n, 1):
         
        # Unsorted pair found
        if (arr[i - 1] > arr[i]):
            return False
 
    # No unsorted pair found
    return True
 
# Driver code
if __name__ == '__main__':
    arr = [19, 23, 25, 30, 45]
    n = len(arr)
     
    if (isInorder(arr, n)):
        print("Yes")
    else:
        print("No")
         
# This code is contributed by
# Sahil_Shelangia

Time complexity: linear
Space complexity: constant