Banana-Leopard/TASTY huggingface dataset:
# Python3 program to find distance of
# a given node from root.
 
# A class to create a new Binary
# Tree Node
class newNode:
    def __init__(self, item):
        self.data = item
        self.left = self.right = None
 
# Returns -1 if x doesn't exist in tree.
# Else returns distance of x from root
def findDistance(root, x):
     
    # Base case
    if (root == None):
        return -1
 
    # Initialize distance
    dist = -1
 
    # Check if x is present at root or
    # in left subtree or right subtree.
    if (root.data == x):
        return dist + 1
    else:
        dist = findDistance(root.left, x)
        if dist >= 0:
            return dist + 1
        else:
            dist = findDistance(root.right, x)
            if dist >= 0:
                return dist + 1
 
    return dist
 
# Driver Code
if __name__ == '__main__':
 
    root = newNode(5)
    root.left = newNode(10)
    root.right = newNode(15)
    root.left.left = newNode(20)
    root.left.right = newNode(25)
    root.left.right.right = newNode(45)
    root.right.left = newNode(30)
    root.right.right = newNode(35)
 
    print(findDistance(root, 45))
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: constant
# Python3 program to print right sibling
# of a node
 
# A class to create a new Binary
# Tree Node
class newNode:
    def __init__(self, item, parent):
        self.data = item
        self.left = self.right = None
        self.parent = parent
 
# Method to find right sibling
def findRightSibling(node, level):
    if (node == None or node.parent == None):
        return None   
 
    # GET Parent pointer whose right child is not
    # a parent or itself of this node. There might
    # be case when parent has no right child, but,
    # current node is left child of the parent
    # (second condition is for that).
    while (node.parent.right == node or
          (node.parent.right == None and
           node.parent.left == node)):
        if (node.parent == None):
            return None
 
        node = node.parent
        level -= 1
 
    # Move to the required child, where
    # right sibling can be present
    node = node.parent.right
 
    # find right sibling in the given subtree
    # (from current node), when level will be 0
    while (level < 0):
 
        # Iterate through subtree
        if (node.left != None):
            node = node.left
        else if (node.right != None):
            node = node.right
        else:
 
            # if no child are there, we cannot
            # have right sibling in this path
            break
         
        level += 1
 
    if (level == 0):
        return node    
 
    # This is the case when we reach 9 node
    # in the tree, where we need to again
    # recursively find the right sibling
    return findRightSibling(node, level)
 
# Driver Code
if __name__ == '__main__':
    root = newNode(1, None)
    root.left = newNode(2, root)
    root.right = newNode(3, root)
    root.left.left = newNode(4, root.left)
    root.left.right = newNode(6, root.left)
    root.left.left.left = newNode(7, root.left.left)
    root.left.left.left.left = newNode(10, root.left.left.left)
    root.left.right.right = newNode(9, root.left.right)
    root.right.right = newNode(5, root.right)
    root.right.right.right = newNode(8, root.right.right)
    root.right.right.right.right = newNode(12, root.right.right.right)
 
    # passing 10
    res = findRightSibling(root.left.left.left.left, 0)
    if (res == None):
        print("No right sibling")
    else:
        print(res.data)
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: constant
# Python3 program to find next right of a
# given key using preorder traversal
 
# class to create a new tree node
class newNode:
    def __init__(self, key):
        self.key = key
        self.left = self.right = None
 
# Function to find next node for given node
# in same level in a binary tree by using
# pre-order traversal
def nextRightNode(root, k, level, value_level):
     
    # return None if tree is empty
    if (root == None):
        return None
 
    # if desired node is found, set
    # value_level to current level
    if (root.key == k):
        value_level[0] = level
        return None
 
    # if value_level is already set, then
    # current node is the next right node
    elif (value_level[0]):
        if (level == value_level[0]):
            return root
 
    # recurse for left subtree by increasing
    # level by 1
    leftNode = nextRightNode(root.left, k,
                             level + 1, value_level)
 
    # if node is found in left subtree,
    # return it
    if (leftNode):
        return leftNode
 
    # recurse for right subtree by
    # increasing level by 1
    return nextRightNode(root.right, k,
                         level + 1, value_level)
 
# Function to find next node of given node
# in the same level in given binary tree
def nextRightNodeUtil(root, k):
    value_level = [0]
 
    return nextRightNode(root, k, 1, value_level)
 
# A utility function to test above functions
def test(root, k):
    nr = nextRightNodeUtil(root, k)
    if (nr != None):
        print("Next Right of", k, "is", nr.key)
    else:
        print("No next right node found for", k)
 
# Driver Code
if __name__ == '__main__':
     
    # Let us create binary tree given in the
    # above example
    root = newNode(10)
    root.left = newNode(2)
    root.right = newNode(6)
    root.right.right = newNode(5)
    root.left.left = newNode(8)
    root.left.right = newNode(4)
 
    test(root, 10)
    test(root, 2)
    test(root, 6)
    test(root, 5)
    test(root, 8)
    test(root, 4)
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: constant
# Python3 Program to find Tilt of
# Binary Tree
 
# class that allocates a new node
# with the given data and
# None left and right pointers.
class newNode:
    def __init__(self, data):
        self.val = data
        self.left = self.right = None
 
# Recursive function to calculate
# Tilt of whole tree
def traverse(root, tilt):
    if (not root):
        return 0
 
    # Compute tilts of left and right subtrees
    # and find sums of left and right subtrees
    left = traverse(root.left, tilt)
    right = traverse(root.right, tilt)
 
    # Add current tilt to overall
    tilt[0] += abs(left - right)
 
    # Returns sum of nodes under
    # current tree
    return left + right + root.val
 
# Driver function to print Tilt
# of whole tree
def Tilt(root):
    tilt = [0]
    traverse(root, tilt)
    return tilt[0]
 
# Driver code
if __name__ == '__main__':
     
    # Let us construct a Binary Tree
    #     4
    #    / \
    #   2   9
    #  / \   \
    # 3   5   7
    root = None
    root = newNode(4)
    root.left = newNode(2)
    root.right = newNode(9)
    root.left.left = newNode(3)
    root.left.right = newNode(8)
    root.right.right = newNode(7)
    print("The Tilt of whole tree is",
                           Tilt(root))
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: linear
# Python3 program to find averages of
# all levels in a binary tree.
 
# Helper function 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 = self.right = None
 
def inorder(node, m):
    if (not node):
        return ""
 
    Str = "("
    Str += inorder(node.left, m)
    Str += str(node.data)
    Str += inorder(node.right, m)
    Str += ")"
 
    # Subtree already present (Note that
    # we use unordered_map instead of
    # unordered_set because we want to print
    # multiple duplicates only once, consider
    # example of 4 in above subtree, it
    # should be printed only once.
    if (Str in m and m[Str] == 1):
        print(node.data, end = " ")
    if Str in m:
        m[Str] += 1
    else:
        m[Str] = 1
 
    return Str
 
# Wrapper over inorder()
def printAllDups(root):
    m = {}
    inorder(root, m)
 
# Driver code
if __name__ == '__main__':
    root = None
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(4)
    root.right.left = newNode(2)
    root.right.left.left = newNode(4)
    root.right.right = newNode(4)
    printAllDups(root)
 
# This code is contributed by PranchalK

Time complexity: quadratic
Space complexity: quadratic
# Python3 program to find largest three
# elements in a binary tree.
 
# Helper function 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
   
# function to find three largest element
def threelargest(root, first, second, third):
  if (root == None):
    return
    
  # if data is greater than first large
  # number update the top three list
  if (root.data > first[0]):
    third[0] = second[0]
    second[0] = first[0]
    first[0] = root.data
    
  # if data is greater than second large
  # number and not equal to first update
  # the bottom two list
  elif (root.data > second[0] and
        root.data != first[0]):
    third[0] = second[0]
    second[0] = root.data
    
  # if data is greater than third large
  # number and not equal to first & second
  # update the third highest list
  elif (root.data > third[0] and
        root.data != first[0] and
        root.data != second[0]):
      third[0] = root.data
    
  threelargest(root.left, first,
                  second, third)
  threelargest(root.right, first,
                   second, third)
 
# Driver Code
if __name__ == '__main__':
 
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(4)
    root.left.right = newNode(5)
    root.right.left = newNode(4)
    root.right.right = newNode(5)
     
    first = [0]
    second = [0]
    third = [0]
    threelargest(root, first, second, third)
    print("three largest elements are",
           first[0], second[0], third[0])
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: constant
# Python3 program to print DFS traversal
# from a given  graph
from collections import defaultdict
 
# This class represents a directed graph using
# adjacency list representation
 
 
class Graph:
 
    # Constructor
    def __init__(self):
 
        # default dictionary to store graph
        self.graph = defaultdict(list)
 
    # function to add an edge to graph
    def addEdge(self, u, v):
        self.graph[u].append(v)
 
    # A function used by DFS
    def DFSUtil(self, v, visited):
 
        # Mark the current node as visited
        # and print it
        visited.add(v)
        print(v, end=' ')
 
        # Recur for all the vertices
        # adjacent to this vertex
        for neighbour in self.graph[v]:
            if neighbour not in visited:
                self.DFSUtil(neighbour, visited)
 
    # The function to do DFS traversal. It uses
    # recursive DFSUtil()
    def DFS(self, v):
 
        # Create a set to store visited vertices
        visited = set()
 
        # Call the recursive helper function
        # to print DFS traversal
        self.DFSUtil(v, visited)
 
# Driver's code
 
 
# Create a graph given
# in the above diagram
if __name__ == "__main__":
    g = Graph()
    g.addEdge(0, 1)
    g.addEdge(0, 2)
    g.addEdge(1, 2)
    g.addEdge(2, 0)
    g.addEdge(2, 3)
    g.addEdge(3, 3)
 
    print("Following is DFS from (starting from vertex 2)")
    # Function call
    g.DFS(2)
 
# This code is contributed by Neelam Yadav

Time complexity: linear
Space complexity: linear
'''Python3 program to print DFS traversal for complete graph'''
from collections import defaultdict
 
# this class represents a directed graph using adjacency list representation
 
 
class Graph:
    # Constructor
    def __init__(self):
        # default dictionary to store graph
        self.graph = defaultdict(list)
 
    # Function to add an edge to graph
    def addEdge(self, u, v):
        self.graph[u].append(v)
    # A function used by DFS
 
    def DFSUtil(self, v, visited):
        # Mark the current node as visited and print it
        visited.add(v)
        print(v, end=" ")
 
        # recur for all the vertices adjacent to this vertex
        for neighbour in self.graph[v]:
            if neighbour not in visited:
                self.DFSUtil(neighbour, visited)
        # The function to do DFS traversal. It uses recursive DFSUtil
 
    def DFS(self):
        # create a set to store all visited vertices
        visited = set()
        # call the recursive helper function to print DFS traversal starting from all
        # vertices one by one
        for vertex in self.graph:
            if vertex not in visited:
                self.DFSUtil(vertex, visited)
# Driver's code
# create a graph given in the above diagram
 
if __name__ == "__main__":
  print("Following is Depth First Traversal \n")
  g = Graph()
  g.addEdge(0, 1)
  g.addEdge(0, 2)
  g.addEdge(1, 2)
  g.addEdge(2, 0)
  g.addEdge(2, 3)
  g.addEdge(3, 3)
 
  # Function call
  g.DFS()
 
# Improved by Dheeraj Kumar

Time complexity: linear
Space complexity: linear
# Python3 program to find a mother vertex in O(V+E) time
from collections import defaultdict
 
# This class represents a directed graph using adjacency list
# representation
 
 
class Graph:
 
    def __init__(self, vertices):
        self.V = vertices  # No. of vertices
        self.graph = defaultdict(list)  # default dictionary
 
    # A recursive function to print DFS starting from v
    def DFSUtil(self, v, visited):
 
        # Mark the current node as visited and print it
        visited[v] = True
 
        # Recur for all the vertices adjacent to this vertex
        for i in self.graph[v]:
            if visited[i] == False:
                self.DFSUtil(i, visited)
 
    # Add w to the list of v
    def addEdge(self, v, w):
        self.graph[v].append(w)
 
    # Returns a mother vertex if exists. Otherwise returns -1
    def findMother(self):
 
        # visited[] is used for DFS. Initially all are
        # initialized as not visited
        visited = [False]*(self.V)
 
        # To store last finished vertex (or mother vertex)
        v = 0
 
        # Do a DFS traversal and find the last finished
        # vertex
        for i in range(self.V):
            if visited[i] == False:
                self.DFSUtil(i, visited)
                v = i
 
        # If there exist mother vertex (or vertices) in given
        # graph, then v must be one (or one of them)
 
        # Now check if v is actually a mother vertex (or graph
        # has a mother vertex). We basically check if every vertex
        # is reachable from v or not.
 
        # Reset all values in visited[] as false and do
        # DFS beginning from v to check if all vertices are
        # reachable from it or not.
        visited = [False]*(self.V)
        self.DFSUtil(v, visited)
        if any(i == False for i in visited):
            return -1
        else:
            return v
 
 
# Driver code
if __name__ == '__main__':
  g = Graph(7)
  g.addEdge(0, 1)
  g.addEdge(0, 2)
  g.addEdge(1, 3)
  g.addEdge(4, 1)
  g.addEdge(6, 4)
  g.addEdge(5, 6)
  g.addEdge(5, 2)
  g.addEdge(6, 0)
 
  # Function call
  print("A mother vertex is " + str(g.findMother()))
 
# This code is contributed by Neelam Yadav

Time complexity: linear
Space complexity: linear
# Python 3 program to count all paths
# from a source to a destination.
 
# A directed graph using adjacency
# list representation
 
 
class Graph:
 
    def __init__(self, V):
        self.V = V
        self.adj = [[] for i in range(V)]
 
    def addEdge(self, u, v):
 
        # Add v to u’s list.
        self.adj[u].append(v)
 
    # Returns count of paths from 's' to 'd'
    def countPaths(self, s, d):
 
        # Mark all the vertices
        # as not visited
        visited = [False] * self.V
 
        # Call the recursive helper
        # function to print all paths
        pathCount = [0]
        self.countPathsUtil(s, d, visited, pathCount)
        return pathCount[0]
 
    # A recursive function to print all paths
    # from 'u' to 'd'. visited[] keeps track
    # of vertices in current path. path[]
    # stores actual vertices and path_index
    # is current index in path[]
    def countPathsUtil(self, u, d,
                       visited, pathCount):
        visited[u] = True
 
        # If current vertex is same as
        # destination, then increment count
        if (u == d):
            pathCount[0] += 1
 
        # If current vertex is not destination
        else:
 
            # Recur for all the vertices
            # adjacent to current vertex
            i = 0
            while i < len(self.adj[u]):
                if (not visited[self.adj[u][i]]):
                    self.countPathsUtil(self.adj[u][i], d,
                                        visited, pathCount)
                i += 1
 
        visited[u] = False
 
 
# Driver Code
if __name__ == '__main__':
 
    # Create a graph given in the
    # above diagram
    g = Graph(4)
    g.addEdge(0, 1)
    g.addEdge(0, 2)
    g.addEdge(0, 3)
    g.addEdge(2, 0)
    g.addEdge(2, 1)
    g.addEdge(1, 3)
 
    s = 2
    d = 3
     
    # Function call
    print(g.countPaths(s, d))
 
# This code is contributed by PranchalK

Time complexity: np
Space complexity: linear
# Python3 Program to determine level
# of each node and print level
import queue
 
# function to determine level of
# each node starting from x using BFS
 
 
def printLevels(graph, V, x):
 
    # array to store level of each node
    level = [None] * V
    marked = [False] * V
 
    # create a queue
    que = queue.Queue()
 
    # enqueue element x
    que.put(x)
 
    # initialize level of source
    # node to 0
    level[x] = 0
 
    # marked it as visited
    marked[x] = True
 
    # do until queue is empty
    while (not que.empty()):
 
        # get the first element of queue
        x = que.get()
 
        # traverse neighbors of node x
        for i in range(len(graph[x])):
 
            # b is neighbor of node x
            b = graph[x][i]
 
            # if b is not marked already
            if (not marked[b]):
 
                # enqueue b in queue
                que.put(b)
 
                # level of b is level of x + 1
                level[b] = level[x] + 1
 
                # mark b
                marked[b] = True
 
    # display all nodes and their levels
    print("Nodes", " ", "Level")
    for i in range(V):
        print(" ", i,  " --> ", level[i])
 
 
# Driver Code
if __name__ == '__main__':
 
    # adjacency graph for tree
    V = 8
    graph = [[] for i in range(V)]
 
    graph[0].append(1)
    graph[0].append(2)
    graph[1].append(3)
    graph[1].append(4)
    graph[1].append(5)
    graph[2].append(5)
    graph[2].append(6)
    graph[6].append(7)
 
    # call levels function with source as 0
    printLevels(graph, V, 0)
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: linear
# Python3 program to print all paths of
# source to destination in given graph
from typing import List
from collections import deque
 
# Utility function for printing
# the found path in graph
def printpath(path: List[int]) -> None:
     
    size = len(path)
    for i in range(size):
        print(path[i], end = " ")
         
    print()
 
# Utility function to check if current
# vertex is already present in path
def isNotVisited(x: int, path: List[int]) -> int:
 
    size = len(path)
    for i in range(size):
        if (path[i] == x):
            return 0
             
    return 1
 
# Utility function for finding paths in graph
# from source to destination
def findpaths(g: List[List[int]], src: int,
              dst: int, v: int) -> None:
                   
    # Create a queue which stores
    # the paths
    q = deque()
 
    # Path vector to store the current path
    path = []
    path.append(src)
    q.append(path.copy())
     
    while q:
        path = q.popleft()
        last = path[len(path) - 1]
 
        # If last vertex is the desired destination
        # then print the path
        if (last == dst):
            printpath(path)
 
        # Traverse to all the nodes connected to
        # current vertex and push new path to queue
        for i in range(len(g[last])):
            if (isNotVisited(g[last][i], path)):
                newpath = path.copy()
                newpath.append(g[last][i])
                q.append(newpath)
 
# Driver code
if __name__ == "__main__":
     
    # Number of vertices
    v = 4
    g = [[] for _ in range(4)]
 
    # Construct a graph
    g[0].append(3)
    g[0].append(1)
    g[0].append(2)
    g[1].append(3)
    g[2].append(0)
    g[2].append(1)
 
    src = 2
    dst = 3
    print("path from src {} to dst {} are".format(
        src, dst))
 
    # Function for finding the paths
    findpaths(g, src, dst, v)
 
# This code is contributed by sanjeev2552

Time complexity: quadratic
Space complexity: quadratic
# Python3 program to find minimum edge
# between given two vertex of Graph
import queue
 
# function for finding minimum
# no. of edge using BFS
def minEdgeBFS(edges, u, v, n):
     
    # visited[n] for keeping track
    # of visited node in BFS
    visited = [0] * n
 
    # Initialize distances as 0
    distance = [0] * n
 
    # queue to do BFS.
    Q = queue.Queue()
    distance[u] = 0
 
    Q.put(u)
    visited[u] = True
    while (not Q.empty()):
        x = Q.get()
         
        for i in range(len(edges[x])):
            if (visited[edges[x][i]]):
                continue
 
            # update distance for i
            distance[edges[x][i]] = distance[x] + 1
            Q.put(edges[x][i])
            visited[edges[x][i]] = 1
    return distance[v]
 
# function for addition of edge
def addEdge(edges, u, v):
    edges[u].append(v)
    edges[v].append(u)
 
# Driver  Code
if __name__ == '__main__':
 
    # To store adjacency list of graph
    n = 9
    edges = [[] for i in range(n)]
    addEdge(edges, 0, 1)
    addEdge(edges, 0, 7)
    addEdge(edges, 1, 7)
    addEdge(edges, 1, 2)
    addEdge(edges, 2, 3)
    addEdge(edges, 2, 5)
    addEdge(edges, 2, 8)
    addEdge(edges, 3, 4)
    addEdge(edges, 3, 5)
    addEdge(edges, 4, 5)
    addEdge(edges, 5, 6)
    addEdge(edges, 6, 7)
    addEdge(edges, 7, 8)
    u = 0
    v = 5
    print(minEdgeBFS(edges, u, v, n))
 
# This code is contributed by PranchalK

Time complexity: linear
Space complexity: linear