BST Insert Operation in DSA C++ - Time & Space Complexity
We want to understand how the time to insert a value into a Binary Search Tree (BST) changes as the tree grows.
How does the number of steps needed to insert a new value grow when the tree has more nodes?
Analyze the time complexity of the following code snippet.
struct Node {
int val;
Node* left;
Node* right;
};
Node* insert(Node* root, int key) {
if (!root) return new Node{key, nullptr, nullptr};
if (key < root->val) root->left = insert(root->left, key);
else root->right = insert(root->right, key);
return root;
}
This code inserts a new value into a BST by moving down the tree until it finds the right spot.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls moving down one level of the tree.
- How many times: Once per tree level until the correct leaf position is found.
Each insert moves down the tree one step at a time, so the number of steps depends on the tree's height.
| Input Size (n) | Approx. Operations (steps down tree) |
|---|---|
| 10 | About 3 to 10 steps |
| 100 | About 7 to 100 steps |
| 1000 | About 10 to 1000 steps |
Pattern observation: If the tree is balanced, steps grow slowly (around log n). If unbalanced, steps can grow as fast as n.
Time Complexity: O(h) where h is the tree height
This means the time depends on how tall the tree is, which can be small if balanced or large if skewed.
[X] Wrong: "Insertion always takes the same time regardless of tree shape."
[OK] Correct: The tree's shape affects how far we must go down. A tall, unbalanced tree means more steps.
Knowing how tree shape affects insert time helps you explain trade-offs and choose the right tree type in real problems.
"What if we used a self-balancing BST like an AVL tree? How would the time complexity change?"
Practice
insert operation in a Binary Search Tree (BST)?Solution
Step 1: Understand BST insert operation
The insert operation adds a new node to the BST while keeping the order property intact: left child < parent < right child.Step 2: Differentiate from other operations
Deleting nodes, finding height, or traversing are different operations and do not describe insertion.Final Answer:
To add a new node while maintaining BST properties -> Option CQuick Check:
Insert = Add node maintaining order [OK]
- Confusing insert with delete operation
- Thinking insert changes tree height only
- Mixing insert with traversal methods
val into a BST using a recursive function in C++?Solution
Step 1: Understand recursive insert signature
Recursive insert usually returns the new root after insertion, so assignment likeroot = insert(root, val);is needed.Step 2: Check other options
Callinginsert(root, val);without assignment ignores updated root.root.insert(val);assumes method on node object which is uncommon.insert(val, root);has wrong parameter order.Final Answer:
root = insert(root, val); -> Option AQuick Check:
Assign returned root after insert [OK]
- Not assigning the returned root after insertion
- Using wrong parameter order in insert call
- Assuming insert is a method of node object
struct Node {
int data;
Node* left;
Node* right;
Node(int val) : data(val), left(nullptr), right(nullptr) {}
};
Node* insert(Node* root, int val) {
if (!root) return new Node(val);
if (val < root->data) root->left = insert(root->left, val);
else root->right = insert(root->right, val);
return root;
}
int main() {
Node* root = nullptr;
root = insert(root, 10);
root = insert(root, 5);
root = insert(root, 15);
root = insert(root, 12);
return 0;
}What is the structure of the BST after these insertions?
Solution
Step 1: Insert 10, 5, 15, 12 step-by-step
Start with empty root. Insert 10 as root. Insert 5 goes left of 10. Insert 15 goes right of 10. Insert 12 goes left of 15.Step 2: Visualize BST structure
Root 10 has left child 5 (no children), right child 15 with left child 12 (no right child).Final Answer:
10 -> 5 -> null (left), 10 -> 15 -> 12 (right subtree) -> Option DQuick Check:
Insert order builds left 5, right 15 with left 12 [OK]
- Placing 12 as right child of 15 instead of left
- Swapping left and right children of 10
- Ignoring null children in output
Node* insert(Node* root, int val) {
if (root == nullptr) {
Node* newNode = new Node(val);
}
if (val < root->data) {
root->left = insert(root->left, val);
} else {
root->right = insert(root->right, val);
}
return root;
}What is the error and how to fix it?
Solution
Step 1: Identify missing return in base case
When root is nullptr, new node is created but not returned, so function continues and dereferences nullptr causing runtime error.Step 2: Fix by returning new node immediately
Addreturn newNode;inside the if block to return the newly created node and stop further execution.Final Answer:
Missing return after creating new node; addreturn newNode;-> Option AQuick Check:
Return new node on nullptr base case [OK]
- Not returning new node causes nullptr dereference
- Changing comparison operator unnecessarily
- Misunderstanding pointer assignments
Solution
Step 1: Insert 15 and 35 into BST
Insert 15: less than 20, greater than 10, goes right of 10. Insert 35: less than 40, greater than 30, goes right of 30.Step 2: Perform in-order traversal
In-order traversal visits nodes in ascending order: left subtree, root, right subtree. The order is 10, 15, 20, 25, 30, 35, 40.Final Answer:
[10, 15, 20, 25, 30, 35, 40] -> Option BQuick Check:
In-order traversal = sorted nodes [OK]
- Placing 15 or 35 in wrong subtree
- Confusing traversal order
- Listing nodes unsorted in output
Ready to prove it?
Pass the test and this pattern moves unknown
