Discover how to instantly find the 'just before' value in a sorted tree without scanning everything!
Why BST Inorder Predecessor in DSA C?
Imagine you have a family tree drawn on paper, and you want to find the person who came just before someone in the family history. Doing this by scanning the whole paper every time is tiring and confusing.
Manually searching for the previous person means checking many names one by one. This takes a lot of time and you might miss or confuse names, especially if the tree is big.
The BST Inorder Predecessor helps you quickly find the person who comes just before another in the sorted order, without checking everyone. It uses the tree's structure to jump directly to the right place.
int findPredecessor(int arr[], int size, int value) {
int predecessor = -1;
for (int i = 0; i < size; i++) {
if (arr[i] < value && arr[i] > predecessor) {
predecessor = arr[i];
}
}
return predecessor;
}Node* findInorderPredecessor(Node* root, int value) {
Node* predecessor = NULL;
Node* current = root;
while (current != NULL) {
if (value <= current->data) {
current = current->left;
} else {
predecessor = current;
current = current->right;
}
}
return predecessor;
}This concept lets you find the immediate smaller value in a sorted tree quickly and reliably, making searching and updating data efficient.
In a contact list sorted by names, finding the person whose name comes just before another helps in quick navigation and suggestions.
Manual search is slow and error-prone for finding previous elements.
BST Inorder Predecessor uses tree structure for fast, direct access.
It enables efficient data retrieval in sorted order.
Practice
Solution
Step 1: Understand inorder traversal in BST
Inorder traversal visits nodes in ascending order of their values.Step 2: Define inorder predecessor
The inorder predecessor of a node is the node visited just before it in inorder traversal, which means it has the largest value smaller than the current node.Final Answer:
The node with the largest value smaller than the given node -> Option AQuick Check:
Inorder predecessor = largest smaller value [OK]
- Confusing predecessor with successor
- Thinking predecessor is always left child
- Assuming predecessor is the parent node
node in a BST when the node has a left subtree?Solution
Step 1: Identify inorder predecessor in left subtree
If node has a left child, predecessor is the rightmost node in left subtree.Step 2: Trace code logic
Starting from node->left, moving right until right child is NULL finds the rightmost node.Final Answer:
Node* pred = node->left; while (pred->right != NULL) pred = pred->right; -> Option AQuick Check:
Left subtree's rightmost node = predecessor [OK]
- Going right subtree instead of left
- Moving left repeatedly instead of right
- Starting from node->right instead of node->left
20
/ \
10 30
\ \
15 40
Solution
Step 1: Locate node 15 and check left subtree
Node 15 has no left child, so predecessor is an ancestor smaller than 15.Step 2: Find nearest ancestor smaller than 15
Ancestor 10 is smaller than 15 and is the closest on the path to root.Final Answer:
10 -> Option DQuick Check:
Predecessor of 15 is 10 [OK]
- Choosing node itself as predecessor
- Choosing larger ancestor like 20
- Confusing predecessor with successor
Node* inorderPredecessor(Node* root, Node* node) {
if (node->left != NULL) {
Node* pred = node->left;
while (pred->left != NULL) {
pred = pred->left;
}
return pred;
}
Node* pred = NULL;
Node* ancestor = root;
while (ancestor != node) {
if (node->data > ancestor->data) {
pred = ancestor;
ancestor = ancestor->right;
} else {
ancestor = ancestor->left;
}
}
return pred;
}
What is the main error in this code?Solution
Step 1: Analyze left subtree traversal
In left subtree, predecessor is rightmost node, so loop should move right, not left.Step 2: Check code loop
Code incorrectly moves left repeatedly, so it finds leftmost node instead of rightmost.Final Answer:
The while loop should move right in left subtree, not left -> Option CQuick Check:
Left subtree traversal must go right for predecessor [OK]
- Moving left instead of right in left subtree
- Ignoring ancestor traversal logic
- Assuming predecessor is always left child
node that has no left child. Which approach correctly finds the predecessor?Solution
Step 1: Understand no left child case
If node has no left child, predecessor is an ancestor where node is in right subtree.Step 2: Use parent pointers to find such ancestor
Move up until current node is right child of its parent; that parent is predecessor.Final Answer:
Move up using parent pointers until you find a node which is right child of its parent; then return that parent -> Option BQuick Check:
Go up to right-child parent for predecessor [OK]
- Stopping at left child parent
- Returning sibling nodes incorrectly
- Assuming predecessor is always child node
Ready to prove it?
Pass the test and this pattern moves unknown
