Banana-Leopard/TASTY huggingface dataset:
# Python3 program to find pairs with given
# sum such that one element of pair exists
# in one BST and other in other BST.
 
# A utility function to create a new
# BST node with key as given num
class newNode:
 
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# A utility function to insert a
# given key to BST
def insert(root, key):
    if root == None:
        return newNode(key)
    if root.data > key:
        root.left = insert(root.left, key)
    else:
        root.right = insert(root.right, key)
    return root
 
# store storeInorder traversal in
# auxiliary array
def storeInorder(ptr, vect):
    if ptr == None:
        return
    storeInorder(ptr.left, vect)
    vect.append(ptr.data)
    storeInorder(ptr.right, vect)
 
# Function to find pair for given
# sum in different bst
# vect1[] --> stores storeInorder traversal
#             of first bst
# vect2[] --> stores storeInorder traversal
#             of second bst
def pairSumUtil(vect1, vect2, Sum):
     
    # Initialize two indexes to two
    # different corners of two lists.
    left = 0
    right = len(vect2) - 1
 
    # find pair by moving two corners.
    while left < len(vect1) and right >= 0:
         
        # If we found a pair
        if vect1[left] + vect2[right] == Sum:
            print("(", vect1[left], ",",
                       vect2[right], "),", end = " ")
            left += 1
            right -= 1
 
        # If sum is more, move to higher
        # value in first lists.
        else if vect1[left] + vect2[right] < Sum:
            left += 1
 
        # If sum is less, move to lower
        # value in second lists.
        else:
            right -= 1
 
# Prints all pairs with given "sum" such that one
# element of pair is in tree with root1 and other
# node is in tree with root2.
def pairSum(root1, root2, Sum):
     
    # Store inorder traversals of
    # two BSTs in two lists.
    vect1 = []
    vect2 = []
    storeInorder(root1, vect1)
    storeInorder(root2, vect2)
 
    # Now the problem reduces to finding a
    # pair with given sum such that one 
    # element is in vect1 and other is in vect2.
    pairSumUtil(vect1, vect2, Sum)
 
# Driver Code
if __name__ == '__main__':
     
    # first BST
    root1 = None
    root1 = insert(root1, 8)
    root1 = insert(root1, 10)
    root1 = insert(root1, 3)
    root1 = insert(root1, 6)
    root1 = insert(root1, 1)
    root1 = insert(root1, 5)
    root1 = insert(root1, 7)
    root1 = insert(root1, 14)
    root1 = insert(root1, 13)
 
    # second BST
    root2 = None
    root2 = insert(root2, 5)
    root2 = insert(root2, 18)
    root2 = insert(root2, 2)
    root2 = insert(root2, 1)
    root2 = insert(root2, 3)
    root2 = insert(root2, 4)
 
    Sum = 10
    pairSum(root1, root2, Sum)
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: linear
# Recursive Python program to find key
# closest to k in given Binary Search Tree.
 
# Utility that allocates a new node with the
# given key and NULL left and right pointers.
class newnode:
 
    # Constructor to create a new node
    def __init__(self, data):
        self.key = data
        self.left = None
        self.right = None
 
# Function to find node with minimum
# absolute difference with given K
# min_diff --> minimum difference till now
# min_diff_key --> node having minimum absolute
#                   difference with K
def maxDiffUtil(ptr, k, min_diff, min_diff_key):
    if ptr == None:
        return
         
    # If k itself is present
    if ptr.key == k:
        min_diff_key[0] = k
        return
 
    # update min_diff and min_diff_key by 
    # checking current node value
    if min_diff > abs(ptr.key - k):
        min_diff = abs(ptr.key - k)
        min_diff_key[0] = ptr.key
 
    # if k is less than ptr->key then move
    # in left subtree else in right subtree
    if k < ptr.key:
        maxDiffUtil(ptr.left, k, min_diff,
                                 min_diff_key)
    else:
        maxDiffUtil(ptr.right, k, min_diff,
                                  min_diff_key)
 
# Wrapper over maxDiffUtil()
def maxDiff(root, k):
     
    # Initialize minimum difference
    min_diff, min_diff_key = 999999999999, [-1]
 
    # Find value of min_diff_key (Closest
    # key in tree with k)
    maxDiffUtil(root, k, min_diff, min_diff_key)
 
    return min_diff_key[0]
 
# Driver Code
if __name__ == '__main__':
    root = newnode(9)
    root.left = newnode(4)
    root.right = newnode(17)
    root.left.left = newnode(3)
    root.left.right = newnode(6)
    root.left.right.left = newnode(5)
    root.left.right.right = newnode(7)
    root.right.right = newnode(22)
    root.right.right.left = newnode(20)
    k = 18
    print(maxDiff(root, k))
 
# This code is contributed by PranchalK

Time complexity: constant
Space complexity: constant
#User function Template for python3
IMIN = -2147483648
IMAX = 2147483647
def largestBst(root):
        if root==None:
            return IMAX,IMIN,0
        if (root.left==None and root.right==None):
            return root.data,root.data,1
         
        left=largestBst(root.left)
        right=largestBst(root.right)
 
         
        ans=[0,0,0]
         
        if left[1]<root.data and right[0]>root.data:
            ans[0]=min(left[0],right[0],root.data)
            ans[1]=max(right[1],left[1],root.data)
            ans[2]=1+left[2]+right[2]
            return ans
 
        ans[0]=IMIN
        ans[1]=IMAX
        ans[2]=max(left[2],right[2])
        return ans
 
def largestBstUtil(root):
      # Return the size of the largest sub-tree which is also a BST
     return largestBst(root)[2]
     
#  Driver Code Starts
import sys
sys.setrecursionlimit(1000000)
from collections import deque
# Tree Node
class newNode:
    def __init__(self, val):
        self.right = None
        self.data = val
        self.left = None
 
# Driver Code
if __name__ == '__main__':
      
    """Let us construct the following Tree
        50
        / \
        75 45
    /
    40 """
    root = newNode(50)
    root.left = newNode(75)
    root.right = newNode(45)
    root.left.left = newNode(40)
    print("Size of the largest BST is",largestBstUtil(root))

Time complexity: linear
Space complexity: linear
# Python3 program to add all greater values
# in every node of BST
 
# A utility function to create a
# new BST node
class newNode:
 
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
 
# Recursive function to add all greater
# values in every node
def modifyBSTUtil(root, Sum):
     
    # Base Case
    if root == None:
        return
 
    # Recur for right subtree
    modifyBSTUtil(root.right, Sum)
 
    # Now Sum[0] has sum of nodes in right
    # subtree, add root.data to sum and
    # update root.data
    Sum[0] = Sum[0] + root.data
    root.data = Sum[0]
 
    # Recur for left subtree
    modifyBSTUtil(root.left, Sum)
 
# A wrapper over modifyBSTUtil()
def modifyBST(root):
    Sum = [0]
    modifyBSTUtil(root, Sum)
 
# A utility function to do inorder
# traversal of BST
def inorder(root):
    if root != None:
        inorder(root.left)
        print(root.data, end =" ")
        inorder(root.right)
 
# A utility function to insert a new node
# with given data in BST
def insert(node, data):
     
    # If the tree is empty, return a new node
    if node == None:
        return newNode(data)
 
    # 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
 
# 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)
 
    modifyBST(root)
 
    # print inorder traversal of the
    # modified BST
    inorder(root)
     
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: constant
# Python3 program to correct the BST 
# if two nodes are swapped
class Node:
     
    # Constructor to create a new node
    def __init__(self, data):
         
        self.key = data
        self.left = None
        self.right = None
 
# Utility function to track the nodes
# that we have to swap
def correctBstUtil(root, first, middle,
                   last, prev):
                        
    if(root):
         
        # Recur for the left sub tree
        correctBstUtil(root.left, first,
                       middle, last, prev)
                        
        # If this is the first violation, mark these
        # two nodes as 'first and 'middle'
        if(prev[0] and root.key < prev[0].key):
            if(not first[0]):
                first[0] = prev[0]
                middle[0] = root
            else:
                 
                # If this is the second violation,
                # mark this node as last
                last[0] = root
                 
        prev[0] = root
         
        # Recur for the right subtree
        correctBstUtil(root.right, first,
                       middle, last, prev)
     
# A function to fix a given BST where
# two nodes are swapped. This function
# uses correctBSTUtil() to find out two
# nodes and swaps the nodes to fix the BST
def correctBst(root):
     
    # Followed four lines just for forming
    # an array with only index 0 filled
    # with None and we will update it accordingly.
    # we made it null so that we can fill
    # node data in them.
    first = [None]
    middle = [None]
    last = [None]
    prev = [None]
     
    # Setting arrays (having zero index only)
    # for capturing the required node
    correctBstUtil(root, first, middle,
                   last, prev)
 
    # Fixing the two nodes
    if(first[0] and last[0]):
         
        # Swapping for first and last key values
        first[0].key, last[0].key = (last[0].key,
                                    first[0].key)
 
    elif(first[0] and middle[0]):
     
        # Swapping for first and middle key values
        first[0].key, middle[0].key = (middle[0].key,
                                        first[0].key)
     
    # else tree will be fine
 
# Function to print inorder
# traversal of tree
def PrintInorder(root):
     
    if(root):
        PrintInorder(root.left)
        print(root.key, end = " ")
        PrintInorder(root.right)
         
    else:
        return
 
# Driver code
 
#      6
#     /   \
#   10    2
#  / \   / \
# 1   3 7   12
 
# Following 7 lines are for tree formation
root = Node(6)
root.left = Node(10)
root.right = Node(2)
root.left.left = Node(1)
root.left.right = Node(3)
root.right.left = Node(7)
root.right.right = Node(12)
 
# Printing inorder traversal of normal tree
print("inorder traversal of normal tree")
PrintInorder(root)
print("")
 
# Function call to do the task
correctBst(root)
 
# Printing inorder for corrected Bst tree
print("")
print("inorder for corrected BST")
 
PrintInorder(root)
 
# This code is contributed by rajutkarshai

Time complexity: linear
Space complexity: linear
# Python program to find ceil of a given value in BST
 
# A Binary tree node
 
 
class Node:
 
    # Constructor to create a new node
    def __init__(self, data):
        self.key = data
        self.left = None
        self.right = None
 
# Function to find ceil of a given input in BST. If input
# is more than the max key in BST, return -1
 
 
def ceil(root, inp):
 
    # Base Case
    if root == None:
        return -1
 
    # We found equal key
    if root.key == inp:
        return root.key
 
    # If root's key is smaller, ceil must be in right subtree
    if root.key < inp:
        return ceil(root.right, inp)
 
    # Else, either left subtree or root has the ceil value
    val = ceil(root.left, inp)
    return val if val >= inp else root.key
 
 
# Driver code
if __name__ == '__main__':
    root = Node(8)
 
    root.left = Node(4)
    root.right = Node(12)
 
    root.left.left = Node(2)
    root.left.right = Node(6)
 
    root.right.left = Node(10)
    root.right.right = Node(14)
 
    for i in range(16):
        print "% d % d" % (i, ceil(root, i))
 
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

Time complexity: logn
Space complexity: logn
# Python program to find Floor of a given value in BST
 
# A Binary tree node
 
 
class Node:
 
    # Constructor to create a new node
    def __init__(self, data):
        self.key = data
        self.left = None
        self.right = None
 
# Function to find Floor of a given input in BST. If input
# is more than the max key in BST, return -1
 
 
def Floor(root, inp):
 
    # Base Case
    if root == None:
        return -1
 
    # We found equal key
    if root.key == inp:
        return root.key
 
    # If root's key is larger, Floor must be in left subtree
    if root.key > inp:
        return Floor(root.left, inp)
 
    # Else, either right subtree or root has the Floor value
    else:
        floor = Floor(root.right, inp)
        # exception for -1 because it is being returned in base case
        return floor if floor <= inp and floor != -1 else root.key
 
 
# Driver code
if __name__ == '__main__':
    root = Node(8)
 
    root.left = Node(4)
    root.right = Node(12)
 
    root.left.left = Node(2)
    root.left.right = Node(6)
 
    root.right.left = Node(10)
    root.right.right = Node(14)
 
    for i in range(16):
        print(i, Floor(root, i))
 
# This code is contributed by Shubham Singh

Time complexity: logn
Space complexity: logn
# Python3 program to find floor and
# ceil of a given key in BST
 
# A binary tree node has key,
# . left child and right child
 
 
class Node:
 
    def __init__(self, x):
 
        self.data = x
        self.left = None
        self.right = None
 
# Helper function to find floor and
# ceil of a given key in BST
 
 
def floorCeilBSTHelper(root, key):
 
    global floor, ceil
 
    while (root):
        if (root.data == key):
            ceil = root.data
            floor = root.data
            return
        if (key > root.data):
            floor = root.data
            root = root.right
        else:
            ceil = root.data
            root = root.left
 
# Display the floor and ceil of a given
# key in BST. If key is less than the min
# key in BST, floor will be -1; If key is
# more than the max key in BST, ceil will be -1;
 
 
def floorCeilBST(root, key):
 
    global floor, ceil
 
    # Variables 'floor' and 'ceil'
    # are passed by reference
    floor = -1
    ceil = -1
 
    floorCeilBSTHelper(root, key)
 
    print(key, floor, ceil)
 
 
# Driver code
if __name__ == '__main__':
 
    floor, ceil = -1, -1
 
    root = Node(8)
    root.left = Node(4)
    root.right = Node(12)
    root.left.left = Node(2)
    root.left.right = Node(6)
    root.right.left = Node(10)
    root.right.right = Node(14)
 
    for i in range(16):
        floorCeilBST(root, i)
 
# This code is contributed by mohit kumar 29

Time complexity: logn
Space complexity: constant
# Python3 program to print leaf node from
# preorder of binary search tree.
 
# Binary Search
def binarySearch(inorder, l, r, d):
 
    mid = (l + r) >> 1
    if (inorder[mid] == d):
        return mid
    elif (inorder[mid] > d):
        return binarySearch(inorder, l,
                            mid - 1, d)
    else:
        return binarySearch(inorder,
                            mid + 1, r, d)
 
# Function to print Leaf Nodes by doing
# preorder traversal of tree using
# preorder and inorder arrays.
def leafNodesRec(preorder, inorder,
                      l, r, ind, n):
 
    # If l == r, therefore no right or left subtree.
    # So, it must be leaf Node, print it.
    if(l == r):
        print(inorder[l], end = " ")
        ind[0] = ind[0] + 1
        return
 
    # If array is out of bound, return.
    if (l < 0 or l > r or r >= n):
        return
 
    # Finding the index of preorder element
    # in inorder array using binary search.
    loc = binarySearch(inorder, l, r,
                       preorder[ind[0]])
 
    # Incrementing the index.
    ind[0] = ind[0] + 1
 
    # Finding on the left subtree.
    leafNodesRec(preorder, inorder,    
                 l, loc - 1, ind, n)
 
    # Finding on the right subtree.
    leafNodesRec(preorder, inorder,
                 loc + 1, r, ind, n)
 
# Finds leaf nodes from
# given preorder traversal.
def leafNodes(preorder, n):
 
    # To store inorder traversal
    inorder = [0] * n
     
    # Copy the preorder into another array.
    for i in range(n):
        inorder[i] = preorder[i]
 
    # Finding the inorder by sorting the array.
    inorder.sort()
     
    # Point to the index in preorder.
    ind = [0]
     
    # Print the Leaf Nodes.
    leafNodesRec(preorder, inorder, 0,
                 n - 1, ind, n)
 
 
# Driver Code
preorder = [890, 325, 290, 530, 965]
n = len(preorder)
leafNodes(preorder, n)
 
# This code is contributed
# by SHUBHAMSINGH10

Time complexity: nlogn
Space complexity: linear
# Python3 program to find rank of an
# element in a stream.
 
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
        self.leftSize = 0
 
# Inserting a new Node.
def insert(root, data):
    if root is None:
        return newNode(data)
 
    # Updating size of left subtree.
    if data <= root.data:
        root.left = insert(root.left, data)
        root.leftSize += 1
    else:
        root.right = insert(root.right, data)
    return root
 
# Function to get Rank of a Node x.
def getRank(root, x):
     
    # Step 1.
    if root.data == x:
        return root.leftSize
 
    # Step 2.
    if x < root.data:
        if root.left is None:
            return -1
        else:
            return getRank(root.left, x)
 
    # Step 3.
    else:
        if root.right is None:
            return -1
        else:
            rightSize = getRank(root.right, x)
            if rightSize == -1:
                # x not found in right sub tree, i.e. not found in stream
                return -1
            else:
                return root.leftSize + 1 + rightSize
 
# Driver code
if __name__ == '__main__':
    arr = [5, 1, 4, 4, 5, 9, 7, 13, 3]
    n = len(arr)
    x = 4
 
    root = None
    for i in range(n):
        root = insert(root, arr[i])
 
    print("Rank of", x, "in stream is:",
                       getRank(root, x))
    x = 13
    print("Rank of", x, "in stream is:",
                       getRank(root, x))
    x = 8
    print("Rank of", x, "in stream is:",
                       getRank(root, x))
         
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: linear
# Python3 program to find rank of an
# element in a stream.
 
# Driver code
if __name__ == '__main__':
    a = [5, 1, 14, 4, 15,
            9, 7, 20, 11]
    key = 20
    arraySize = len(a)
    count = 0
    for i in range(arraySize):
        if a[i] <= key:
            count += 1
             
    print("Rank of", key,
          "in stream is:", count - 1)
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: constant
# Python program to insert element in binary tree
class newNode():
 
    def __init__(self, data):
        self.key = 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.key,end = " ")
    inorder(temp.right)
 
 
"""function to insert element in binary tree """
def insert(temp,key):
 
    if not temp:
        root = newNode(key)
        return
    q = []
    q.append(temp)
 
    # Do level order traversal until we find
    # an empty place.
    while (len(q)):
        temp = q[0]
        q.pop(0)
 
        if (not temp.left):
            temp.left = newNode(key)
            break
        else:
            q.append(temp.left)
 
        if (not temp.right):
            temp.right = newNode(key)
            break
        else:
            q.append(temp.right)
     
# Driver code
if __name__ == '__main__':
    root = newNode(10)
    root.left = newNode(11)
    root.left.left = newNode(7)
    root.right = newNode(9)
    root.right.left = newNode(15)
    root.right.right = newNode(8)
 
    print("Inorder traversal before insertion:", end = " ")
    inorder(root)
 
    key = 12
    insert(root, key)
 
    print()
    print("Inorder traversal after insertion:", end = " ")
    inorder(root)
 
# This code is contributed by SHUBHAMSINGH10

Time complexity: linear
Space complexity: np
# Python3 program to illustrate deletion in a 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)
 
# function to delete the given deepest node (d_node) in binary tree
 
 
def deleteDeepest(root, d_node):
    q = []
    q.append(root)
    while(len(q)):
        temp = q.pop(0)
        if temp is d_node:
            temp = None
            return
        if temp.right:
            if temp.right is d_node:
                temp.right = None
                return
            else:
                q.append(temp.right)
        if temp.left:
            if temp.left is d_node:
                temp.left = None
                return
            else:
                q.append(temp.left)
 
# function to delete element in binary tree
 
 
def deletion(root, key):
    if root == None:
        return None
    if root.left == None and root.right == None:
        if root.key == key:
            return None
        else:
            return root
    key_node = None
    q = []
    q.append(root)
    temp = None
    while(len(q)):
        temp = q.pop(0)
        if temp.data == key:
            key_node = temp
        if temp.left:
            q.append(temp.left)
        if temp.right:
            q.append(temp.right)
    if key_node:
        x = temp.data
        deleteDeepest(root, temp)
        key_node.data = x
    return root
 
 
# Driver code
if __name__ == '__main__':
    root = Node(10)
    root.left = Node(11)
    root.left.left = Node(7)
    root.left.right = Node(12)
    root.right = Node(9)
    root.right.left = Node(15)
    root.right.right = Node(8)
    print("The tree before the deletion:")
    inorder(root)
    key = 11
    root = deletion(root, key)
    print()
    print("The tree after the deletion;")
    inorder(root)
 
# This code is contributed by Monika Anandan

Time complexity: linear
Space complexity: linear