BST Delete Operation in DSA Java - Time & Space Complexity
We want to understand how long it takes to remove a value from a Binary Search Tree (BST).
Specifically, how the time grows as the tree gets bigger.
Analyze the time complexity of the following code snippet.
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) return null;
if (key < root.val) {
root.left = deleteNode(root.left, key);
} else if (key > root.val) {
root.right = deleteNode(root.right, key);
} else {
if (root.left == null) return root.right;
else if (root.right == null) return root.left;
TreeNode minNode = findMin(root.right);
root.val = minNode.val;
root.right = deleteNode(root.right, minNode.val);
}
return root;
}
private TreeNode findMin(TreeNode node) {
while (node.left != null) node = node.left;
return node;
}
This code removes a node with a given key from a BST, adjusting the tree to keep its order.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls to find the node to delete and to adjust the tree.
- How many times: At most once per level of the tree, moving down from root to leaf.
- Additional operation: The
findMinmethod loops down the left children to find the smallest node in the right subtree.
As the tree grows, the number of steps depends on the tree's height.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to 4-5 steps (tree height) |
| 100 | Up to 7-8 steps |
| 1000 | Up to 10-11 steps |
Pattern observation: The steps grow roughly with the height of the tree, which can be much smaller than the total nodes if the tree is balanced.
Time Complexity: O(h) where h is the tree height
This means the time to delete depends on how tall the tree is, not just how many nodes it has.
[X] Wrong: "Deleting a node always takes time proportional to the total number of nodes (O(n))."
[OK] Correct: The delete operation only travels down one path from root to leaf, so it depends on the tree height, not all nodes.
Understanding how tree height affects delete time helps you explain efficiency clearly and shows you know how data structure shape impacts performance.
"What if the BST is always perfectly balanced? How would that change the time complexity of delete?"
Practice
Solution
Step 1: Understand leaf node deletion
A leaf node has no children, so removing it does not affect other nodes.Step 2: Effect on parent pointer
The parent's pointer to this node is set to null, effectively removing the node.Final Answer:
The node is simply removed and its parent's pointer is set to null. -> Option AQuick Check:
Leaf node deletion = remove node and set parent's pointer null [OK]
- Thinking the tree needs full restructuring
- Replacing leaf node with predecessor or successor
- Confusing leaf node deletion with internal node deletion
Solution
Step 1: Understand BST delete method signature
The method usually takes the root node and the key to delete, returning the updated root.Step 2: Match method signature
public Node deleteNode(Node root, int key) matches: it takes Node root and int key, returns Node (updated root).Final Answer:
public Node deleteNode(Node root, int key) -> Option DQuick Check:
Delete method returns updated root node [OK]
- Using void return type instead of Node
- Not passing root node as parameter
- Returning boolean or int instead of Node
15
/ \
10 20
/ \ \
8 12 25
Solution
Step 1: Delete node 10 from BST
Node 10 has two children (8 and 12). Replace it with its in-order successor (12) and delete 12.Step 2: Perform in-order traversal after deletion
In-order traversal visits nodes in ascending order: 8, 12, 15, 20, 25.Final Answer:
[8, 12, 15, 20, 25] -> Option BQuick Check:
In-order after deleting 10 = [8, 12, 15, 20, 25] [OK]
- Not replacing node 10 correctly
- Including deleted node 10 in traversal
- Confusing in-order successor with predecessor
public Node deleteNode(Node root, int key) {
if (root == null) return root;
if (key < root.val) root.left = deleteNode(root.left, key);
else if (key > root.val) root.right = deleteNode(root.right, key);
else {
if (root.left == null) return root.right;
else if (root.right == null) return root.left;
Node temp = minValueNode(root.right);
root.val = temp.val;
root.right = deleteNode(root.right, key);
}
return root;
}
private Node minValueNode(Node node) {
Node current = node;
while (current.left != null) current = current.left;
return current;
}
What is the bug in this code?Solution
Step 1: Analyze recursive delete call after replacement
After replacing root.val with temp.val (in-order successor), the successor must be deleted from the right subtree using temp.val.Step 2: Identify the bug
The recursive call uses key (original value) instead of temp.val. Since key < values in right subtree, it won't correctly delete the successor.Step 3: Check other options
A is wrong (minValueNode finds successor correctly). B is wrong (null root handled). D is wrong (updates via recursion).Final Answer:
The recursive call to deleteNode uses key instead of temp.val. -> Option AQuick Check:
Recursive call must use temp.val [OK]
- Thinking minValueNode should find max value
- Confusing key and temp.val in recursive call
- Missing base case for null root
Solution
Step 1: Identify node 20's children
Node 20 has two children: 10 (left) and 25 (right).Step 2: Delete node 20 by replacing with in-order successor
In-order successor is 25. Replace 20 with 25, then delete node 25.Step 3: Perform in-order traversal
Traversal order: 10, 25, 30, 35, 40, 50.Final Answer:
[10, 25, 30, 35, 40, 50] -> Option CQuick Check:
In-order after deleting 20 = [10, 25, 30, 35, 40, 50] [OK]
- Leaving deleted node 20 in traversal
- Removing in-order successor node incorrectly
- Confusing in-order predecessor with successor
Ready to prove it?
Pass the test and this pattern moves unknown
