Implementation of Binary Search Tree

Java
// Java Program to Implement
// Binary Search Tree

class Node {
    int key;
    Node left, right;

    public Node(int item) {
        key = item;
        left = right = null;
    }
}

class BinarySearchTree {
    Node root;

    public BinarySearchTree() {
        root = null;
    }

    // Insertion operation
    void insert(int key) {
        root = insertRec(root, key);
    }

    Node insertRec(Node root, int key) {
        if (root == null) {
            root = new Node(key);
            return root;
        }

        if (key < root.key)
            root.left = insertRec(root.left, key);
        else if (key > root.key)
            root.right = insertRec(root.right, key);

        return root;
    }

    // Deletion operation
    void delete(int key) {
        root = deleteRec(root, key);
    }

    Node deleteRec(Node root, int key) {
        if (root == null)
            return root;

        if (key < root.key)
            root.left = deleteRec(root.left, key);
        else if (key > root.key)
            root.right = deleteRec(root.right, key);
        else {
            if (root.left == null)
                return root.right;
            else if (root.right == null)
                return root.left;

            root.key = minValue(root.right);

            root.right = deleteRec(root.right, root.key);
        }

        return root;
    }

    int minValue(Node root) {
        int minv = root.key;
        while (root.left != null) {
            minv = root.left.key;
            root = root.left;
        }
        return minv;
    }

    // Search operation
    boolean search(int key) {
        return searchRec(root, key);
    }

    boolean searchRec(Node root, int key) {
        if (root == null)
            return false;
        if (root.key == key)
            return true;
        if (root.key < key)
            return searchRec(root.right, key);
        return searchRec(root.left, key);
    }

    // Inorder traversal
    void inorder() {
        inorderRec(root);
        System.out.println("\n");
    }

    void inorderRec(Node root) {
        if (root != null) {
            inorderRec(root.left);
            System.out.print(root.key + " ");
            inorderRec(root.right);
        }
    }

    // Preorder traversal
    void preorder() {
        preorderRec(root);
        System.out.println("\n");
        
    }

    void preorderRec(Node root) {
        if (root != null) {
            System.out.print(root.key + " ");
            preorderRec(root.left);
            preorderRec(root.right);
        }
    }

    // Postorder traversal
    void postorder() {
        postorderRec(root);
        System.out.println("\n");
    }

    void postorderRec(Node root) {
        if (root != null) {
            postorderRec(root.left);
            postorderRec(root.right);
            System.out.print(root.key + " ");
        }
    }

}

// Driver Class
public class Main{
      // Main Function
    public static void main(String[] args) {
        BinarySearchTree tree = new BinarySearchTree();

        // Inserting elements
        tree.insert(50);
        tree.insert(30);
        tree.insert(20);
        tree.insert(40);
        tree.insert(70);
        tree.insert(60);
        tree.insert(80);

        System.out.println("Inorder traversal:");
        tree.inorder();

        // Deleting elements
        tree.delete(20);
        tree.delete(30);

        System.out.println("Inorder traversal after deletion:");
        tree.inorder();

        // Searching for an element
        int searchKey = 70;
        System.out.println("Is " + searchKey + " present in the tree? " + tree.search(searchKey));

        // Traversals
        System.out.println("Preorder traversal:");
        tree.preorder();

        System.out.println("Postorder traversal:");
        tree.postorder();
    }
}

Output:

Inorder traversal:
20 30 40 50 60 70 80

Inorder traversal after deletion:
40 50 60 70 80

Is 70 present in the tree? true
Preorder traversal:
50 40 70 60 80

Postorder traversal:
40 60 80 70 50

Complexity of the Above Method:

Operation

Explanation

Complexity

Insertion Operation

To inserting the new key into the BST, we start from root and recursively traverse the tree until we find the appropriate position to insert the new key. Once we find a node where the new key belongs such as either as the left child or right side, we can insert the new node at the position while maintaining BST property.

  • The time complexity of insertion operation is O(log n).
  • The space complexity of insertion operation is O(1).

Deletion Operation

Delete a node involve from the BST involved three cases:

  1. If the node is to be deleted has no child node, we can simply remove the node.
  2. If the node has one child node, we can simply replace the node with its child node.
  3. If the node has two child nodes, we can find its inorder successor or predecessor.
  • The time complexity of deletion operation is O(log n) in average case and O(n) in worst case.
  • The space complexity of deletion operation is O(1).

Searching Operation

Searching in the BST is done by the starting at root and comparing the target key with current node’s key. If the target key equal to current node’s key, we have found key. If the target is less than current node’s key, we have to left subtree, if is is greater we can move to the right subtree. This process is continue recursively until we found the key or reach the null node.

  • The time complexity of searching operation is O(log n) in average case and O(n) in worst case.
  • The space complexity of searching operation is O(1).

Traversal Operations (Inorder, Preorder, Postorder)

  • In inorder traversal, nodes are visited in the ascending order. We first visit left subtree then root and finally right subtree.
  • In preorder traversal, we visit root node of the tree then left subtree of the tree and finally the right subtree of the tree.
  • In postorder traversal, we visit the left subtree of the tree then right subtree of the tree and finally root of the tree.
  • The time complexity of traversal operations is O(n). Here, n is number of nodes in tree.
  • The space complexity of traversal operation is O(h) because, recursive calls are stored on call stack. If an iterative approach is used, the space complexity is O(n). Here, h is height of the tree, n is number of nodes in tree.

Java Program to Construct a Binary Search Tree

Binary Search Tree (BST) is the widely used data structure in computer science, primarily known for the efficient search, insertion, and deletion operations. It is the type of binary tree where each node has at most two children, referred to as the left child and the right child. Binary Search Tree offers the efficient average-case time complexity for operations such as search, insert, and delete operations is (O(log n)), it makes it suitable for applications requiring fast searching and

In this article, we will learn about Binary Search Tree.

Similar Reads

Organization of a Binary Search Tree

A Binary Search Tree (BST) is organized as a hierarchical structure where each node contains the key value and two pointers to the left and right children. The left child contains keys less than the parent node’s key and the right child key contains keys greater than the parent node’s key. This hierarchical organization allowed for efficient operations such as searching, insertion, and deletion operations....

Implementation of Binary Search Tree:

Java // Java Program to Implement // Binary Search Tree class Node { int key; Node left, right; public Node(int item) { key = item; left = right = null; } } class BinarySearchTree { Node root; public BinarySearchTree() { root = null; } // Insertion operation void insert(int key) { root = insertRec(root, key); } Node insertRec(Node root, int key) { if (root == null) { root = new Node(key); return root; } if (key < root.key) root.left = insertRec(root.left, key); else if (key > root.key) root.right = insertRec(root.right, key); return root; } // Deletion operation void delete(int key) { root = deleteRec(root, key); } Node deleteRec(Node root, int key) { if (root == null) return root; if (key < root.key) root.left = deleteRec(root.left, key); else if (key > root.key) root.right = deleteRec(root.right, key); else { if (root.left == null) return root.right; else if (root.right == null) return root.left; root.key = minValue(root.right); root.right = deleteRec(root.right, root.key); } return root; } int minValue(Node root) { int minv = root.key; while (root.left != null) { minv = root.left.key; root = root.left; } return minv; } // Search operation boolean search(int key) { return searchRec(root, key); } boolean searchRec(Node root, int key) { if (root == null) return false; if (root.key == key) return true; if (root.key < key) return searchRec(root.right, key); return searchRec(root.left, key); } // Inorder traversal void inorder() { inorderRec(root); System.out.println("\n"); } void inorderRec(Node root) { if (root != null) { inorderRec(root.left); System.out.print(root.key + " "); inorderRec(root.right); } } // Preorder traversal void preorder() { preorderRec(root); System.out.println("\n"); } void preorderRec(Node root) { if (root != null) { System.out.print(root.key + " "); preorderRec(root.left); preorderRec(root.right); } } // Postorder traversal void postorder() { postorderRec(root); System.out.println("\n"); } void postorderRec(Node root) { if (root != null) { postorderRec(root.left); postorderRec(root.right); System.out.print(root.key + " "); } } } // Driver Class public class Main{ // Main Function public static void main(String[] args) { BinarySearchTree tree = new BinarySearchTree(); // Inserting elements tree.insert(50); tree.insert(30); tree.insert(20); tree.insert(40); tree.insert(70); tree.insert(60); tree.insert(80); System.out.println("Inorder traversal:"); tree.inorder(); // Deleting elements tree.delete(20); tree.delete(30); System.out.println("Inorder traversal after deletion:"); tree.inorder(); // Searching for an element int searchKey = 70; System.out.println("Is " + searchKey + " present in the tree? " + tree.search(searchKey)); // Traversals System.out.println("Preorder traversal:"); tree.preorder(); System.out.println("Postorder traversal:"); tree.postorder(); } }...

Applications of the BST

Binary Search Trees are find applications in the different domains due to their operations such as efficient search, insertion and deletion operations. Here, some of the key applications of BSTs include:...

Conclusion

In conclusion, Binary Search Tree are the fundamental data structure with the wide range of the applications in computer science. Their ability to efficiently store the data, retrieve the data and manipulate data makes them invaluable in the fields like symbol tables, databases, file systems and algorithms. BSTs are powerful and flexible data structures that will play a main role in the computing. Understanding of their principles and applications is the essential for the software developers and computer scientists seeking the efficient solutions to the variety of the problems....