Java Program to Implement Binary Search Tree
Node class with left and right child references and methods like insert() to add nodes and inorder() to print nodes in sorted order.Examples
How to Think About It
Algorithm
Code
class Node { int data; Node left, right; Node(int data) { this.data = data; left = right = null; } } public class BST { Node root; void insert(int data) { root = insertRec(root, data); } Node insertRec(Node root, int data) { if (root == null) { root = new Node(data); return root; } if (data < root.data) root.left = insertRec(root.left, data); else if (data > root.data) root.right = insertRec(root.right, data); return root; } void inorder() { inorderRec(root); System.out.println(); } void inorderRec(Node root) { if (root != null) { inorderRec(root.left); System.out.print(root.data + " "); inorderRec(root.right); } } public static void main(String[] args) { BST tree = new BST(); tree.insert(5); tree.insert(3); tree.insert(7); tree.inorder(); } }
Dry Run
Let's trace inserting 5, 3, 7 into the BST and then printing inorder.
Insert 5
Root is null, create new node with data 5 as root.
Insert 3
3 < 5, go left of root which is null, insert node with data 3 there.
Insert 7
7 > 5, go right of root which is null, insert node with data 7 there.
Inorder traversal
Visit left subtree (3), root (5), right subtree (7), print in order: 3 5 7
| Step | Current Node | Action |
|---|---|---|
| Insert 5 | null | Create root node with 5 |
| Insert 3 | 5 | 3 < 5, go left, insert 3 |
| Insert 7 | 5 | 7 > 5, go right, insert 7 |
| Inorder | root | Print 3 5 7 |
Why This Works
Step 1: Node Structure
Each Node holds a value and references to left and right children, allowing the tree to branch.
Step 2: Insertion Logic
Insert compares the new value with current node's data and decides to go left or right, maintaining sorted order.
Step 3: Inorder Traversal
Inorder visits left child, node, then right child, printing values in ascending order.
Alternative Approaches
class Node { int data; Node left, right; Node(int data) { this.data = data; left = right = null; } } public class BSTIterative { Node root; void insert(int data) { Node newNode = new Node(data); if (root == null) { root = newNode; return; } Node current = root, parent = null; while (current != null) { parent = current; if (data < current.data) current = current.left; else if (data > current.data) current = current.right; else return; // no duplicates } if (data < parent.data) parent.left = newNode; else parent.right = newNode; } void inorder() { inorderRec(root); System.out.println(); } void inorderRec(Node root) { if (root != null) { inorderRec(root.left); System.out.print(root.data + " "); inorderRec(root.right); } } public static void main(String[] args) { BSTIterative tree = new BSTIterative(); tree.insert(5); tree.insert(3); tree.insert(7); tree.inorder(); } }
import java.util.TreeSet; public class BSTWithTreeSet { public static void main(String[] args) { TreeSet<Integer> tree = new TreeSet<>(); tree.add(5); tree.add(3); tree.add(7); for (int val : tree) { System.out.print(val + " "); } System.out.println(); } }
Complexity: O(h) time, O(h) space
Time Complexity
Insertion and search take O(h) time where h is tree height; balanced trees have h = O(log n), worst case is O(n).
Space Complexity
Recursive insertion uses O(h) stack space; iterative insertion uses O(1) extra space.
Which Approach is Fastest?
Recursive insertion is simpler but iterative uses less memory; built-in TreeSet is fastest for balanced trees but less flexible.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Recursive Insertion | O(h) | O(h) | Simple code, small trees |
| Iterative Insertion | O(h) | O(1) | Memory efficient, larger trees |
| Java TreeSet | O(log n) | O(n) | Quick balanced tree with no manual code |