Binary Search Tree In Python

Last Updated : 21 Sep, 2026

A Binary Search Tree (BST) is a binary tree that maintains its elements in an ordered manner. For every node, values smaller than the node are stored in the left subtree, while larger values are stored in the right subtree. This property makes searching, insertion, and deletion efficient when the tree remains balanced.

  • The left side of a node only has smaller values.
  • The right side of a node only has bigger values.
  • Both the left and right sides follow the same rule, forming a smaller binary search tree.
binary_search_tree_1

For example, consider a BST with 8 as the root:

  • Values smaller than 8, such as 3, are placed on the left.
  • Values greater than 8, such as 10, are placed on the right.
  • The same ordering rule continues for every subtree.

Creation of Binary Search Tree (BST) in Python

Below, are the steps to create a Binary Search Tree (BST).

  • Create a Node class.
  • In the constructor (__init__), initialize the node with a key/value and set its left and right child pointers to None.
Python
class Node:
    def __init__(self, key):
        self.value = key  
        self.left = None  
        self.right = None    
root = Node(5)

Explanation:

  • Node Class: Initializes a node storing key in self.value and sets left and right pointers to None.
  • Instantiation: root = Node(5) creates the root node containing the value 5.

Basic Operations on Binary Search Tree (BST)

Insertion in Binary Search Tree(BST) in Python

Inserting a node in a Binary search tree involves adding a new node to the tree while maintaining the binary search tree (BST) property. So we need to traverse through all the nodes till we find a leaf node and insert the node as the left or right child based on the value of that leaf node.

Let us insert 13 into the below Binary search tree

binary_search_tree_2
  • When we call the insert method, 13 is checked with the root node which is 15. Since $13 < 15$, we need to insert 13 to the left subtree. So we recursively call left_sub_tree.insert(13).
  • The left child of 15 is 10, so 13 is checked with 10. Since $13 > 10$, we need to insert 13 to the right subtree. So we recursively call right_sub_tree.insert(13).
  • The right child of 10 is 11, so 13 is checked with 11. Since $13 > 11$, we need to insert 13 to the right child of 11. Again we recursively call right_sub_tree.insert(13).
  • In this recursion call, we find there is no node (None), which means we reached the leaf node position. So we create a node and insert the data in the node.
binary_search_tree_3

Insertion in Binary Search Tree (BST) in Python

Python
class Node:
    def __init__(self, key):
        self.left = None
        self.right = None
        self.val = key

def insert(root, key):
    if root is None:
        return Node(key)
    if root.val == key:
        return root
    if root.val < key:
        root.right = insert(root.right, key)
    else:
        root.left = insert(root.left, key)
    return root

def inorder(root):
    if root:
        inorder(root.left)
        print(root.val, end=" ")
        inorder(root.right)

r = Node(15)
r = insert(r, 10)
r = insert(r, 18)
r = insert(r, 4)
r = insert(r, 11)
r = insert(r, 16)
r = insert(r, 20)
r = insert(r, 13)

inorder(r)

Output
4 10 11 13 15 16 18 20 

Explanation:

  • Base Case: Returns a new Node(key) if root is None.
  • Duplicate Check: Returns root unchanged if root.val == key to prevent duplicate insertions.
  • Recursive Step: Navigates root.right if key > root.val, or root.left if key < root.val.
  • Verification: inorder(r) traverses the constructed BST in non-decreasing order to display sorted elements.

Time Complexity: 

  • The worst-case time complexity of insert operations is O(h) where h is the height of the Binary Search Tree. 
  • In the worst case, we may have to travel from the root to the deepest leaf node. The height of a skewed tree may become n and the time complexity of insertion operation may become O(n). 

Auxiliary Space: The auxiliary space complexity of insertion into a binary search tree is O(1)

Searching in Binary Search Tree in Python

Searching in a Binary Search Tree (BST) is very efficient because we don't need to traverse all the nodes. It is based on the value of nodes, which means if the value is less than the root, we search in the left subtree; otherwise, we search in the right subtree.

Steps to search a value 'v' in BST:

  • The value is checked with the root node. If it is equal to the root node, it returns the node.
  • If the value is less than the root node, it recursively calls the search operation on the left subtree.
  • If the value is greater than the root node, it recursively calls the search operation on the right subtree.
binary_search_tree_8
  • In above example BST search for value '8' begins from the root node.
  • If the value is not equal to the current node's value, the search continues recursively on the left subtree if the value is less than the current node's value.
  • Once the value matches a node, the search terminates, returning the node containing the value.

Searching in Binary Search Tree (BST) in Python

Python
class Node:
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None

def search(root, key):
    if root is None or root.key == key:
        return root
    
    if root.key < key:
        return search(root.right, key)
    
    return search(root.left, key)
root = Node(50)
root.left = Node(30)
root.right = Node(70)
root.left.left = Node(20)
root.left.right = Node(40)
root.right.left = Node(60)
root.right.right = Node(80)
print("Found" if search(root, 19) else "Not Found")
print("Found" if search(root, 80) else "Not Found")

Output
Not Found
Found

Explanation:

Node Class: Defines a tree node containing a key value along with left and right child references initialized to None.

Search Function (search):

  • Base Cases: Returns root immediately if the tree/subtree is empty (None) or if root.key == key.
  • Right Traversal: If root.key < key, target key is larger, so it searches recursively in root.right.
  • Left Traversal: Otherwise, target key is smaller, so it searches recursively in root.left.
  • Driver Logic: Constructs a sample BST and calls search() for values 19 and 80, printing "Found" or "Not Found" based on whether a valid node is returned.

Time complexity: O(h), where h is the height of the BST.

Auxiliary Space: O(h) This is because of the space needed to store the recursion stack.

Deletion in Binary Search Tree in Python

Deleting a node in a Binary Search Tree (BST) involves removing an existing node while ensuring that the BST properties remain intact. The process consists of two main steps: locating the target node to be deleted, and restructuring the tree based on the node's child structure.

Case 1: While deleting a node having both left child and right child

  • After finding the node to be deleted, copy the value of right child to v and copy the right child's left pointer to left of v and right pointer
binary_search_tree_4
  • In the above example, suppose we need to delete 18 then we need to replace 18 with the maximum value of its left or right sub tree
  • Let us replace it with 20 which is maximum value of right sub tree
  • So after deleting 18, the Binary search tree looks like this
binary_search_tree_6

Case 2: While deleting a node having either left child or right child

  • After finding the node to be deleted, we need to replace the value in the node with its left node it has left child or right node if it has right child.
binary_search_tree_5
  • In the above example, suppose we need to delete 16 then we need to replace 16 with the value of its right child node
  • So it will be replaced with 17 which is the value of its right child node
  • So after deleting 16, the Binary search tree looks like this
binary_search_tree_9

Case 3: While deleting a leaf node(a node which has no child)

Untitled-Diagramdrawio-(9)
Delete 4 in BST
  • In the above example, suppose we need to delete 4 which is a leaf node.
  • Simply we change value of the node, left and right pointers to None.
  • After deleting 4 the BST looks like this:
Untitled-Diagram-(6)
Deleted 4 in BST

Deletion in Binary Search Tree in Python

Python
class Node:
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None

def get_successor(curr):
    curr = curr.right
    while curr is not None and curr.left is not None:
        curr = curr.left
    return curr

def del_node(root, x):
    if root is None:
        return root

    if root.key > x:
        root.left = del_node(root.left, x)
    elif root.key < x:
        root.right = del_node(root.right, x)
    else:
        if root.left is None:
            return root.right

        if root.right is None:
            return root.left

        succ = get_successor(root)
        root.key = succ.key
        root.right = del_node(root.right, succ.key)
        
    return root

def inorder(root):
    if root is not None:
        inorder(root.left)
        print(root.key, end=" ")
        inorder(root.right)

if __name__ == "__main__":
    root = Node(10)
    root.left = Node(5)
    root.right = Node(15)
    root.right.left = Node(12)
    root.right.right = Node(18)
    x = 15

    root = del_node(root, x)
    inorder(root)
    print()

Output
5 10 12 18 

Explanation:

  • Node Class: Initializes a node with a key value and sets left and right child pointers to None.
  • In-order Successor Helper (get_successor): Moves to the right child once, then continuously traverses left pointers to extract the minimum key in the right subtree.

Deletion Logic (del_node):

  • Traversal: Recursively navigates left or right depending on whether x is smaller or larger than root.key.
  • 0 or 1 Child: If root.left is None, it returns root.right (handling leaf nodes returning None and single right-child cases). If root.right is None, it returns root.left.
  • 2 Children: Locates the in-order successor, copies its value to the current node, and recursively deletes that successor node from the right subtree.

Time Complexity: O(h), where h is the height of the BST. 

Auxiliary Space: O(h).

Traversals in Binary Search Tree in Python

Traversing a Binary Search Tree (BST) involves visiting all the nodes in a specific order. Like binary trees, BSTs support three main depth-first traversal techniques:

  • Inorder Traversal: Visits the left subtree, root node, and then the right subtree. This produces keys in sorted ascending order.
  • Preorder Traversal : Visits the root node first, followed by the left subtree and the right subtree.
  • Postorder Traversal : Visits the left subtree, the right subtree, and finally the root node.

Traversals in BST in Python

Python
class Node:
    def __init__(self, v):
        self.left = None
        self.right = None
        self.data = v
def printInorder(root):
    if root:
        printInorder(root.left)
        print(root.data,end=" ")
        printInorder(root.right)

if __name__ == "__main__":
    # Build the tree
    root = Node(100)
    root.left = Node(20)
    root.right = Node(200)
    root.left.left = Node(10)
    root.left.right = Node(30)
    root.right.left = Node(150)
    root.right.right = Node(300)

    print("Inorder Traversal:",end=" ")
    printInorder(root)

Output
Inorder Traversal: 10 20 30 100 150 200 300 

Explanation:

  • printInorder(root): Recursively visits root.left, processes root.data, and then visits root.right. This prints the binary search tree elements in strictly ascending order.
  • printPreorder(root): Processes root.data first, then recursively visits root.left and root.right. Useful for creating a copy of the tree structure.
  • printPostorder(root): Recursively visits root.left and root.right before processing root.data. Commonly used when deleting nodes or freeing tree memory from bottom to top.

Time complexity: O(N), Where N is the number of nodes.
Auxiliary Space: O(h), Where h is the height of tree

Applications

  • Enable fast logarithmic-time data retrieval, making them suitable for indexing structures in database engines and filesystem trees.
  • Standard BST concepts serve as the foundation for balanced variants like AVL Trees and Red-Black Trees, which guarantee optimized lookup times.
  • Can be used to construct dynamic priority queues where minimum or maximum elements are tracked efficiently.
  • BST-backed sets and maps are widely used inside graph algorithms (such as Prim's or Dijkstra's algorithms) to manage dynamic edge weights and vertex sets.
Comment