What is the inorder predecessor in a Binary Search Tree (BST)?
The inorder predecessor of a node in a BST is the node that comes immediately before it in the inorder traversal. It is the largest node smaller than the given node.
Click to reveal answer
beginner
How do you find the inorder predecessor if the node has a left subtree?
If the node has a left subtree, the inorder predecessor is the rightmost (maximum) node in that left subtree.
Click to reveal answer
intermediate
What if the node does not have a left subtree? How to find its inorder predecessor?
If the node has no left subtree, move up the tree using parent pointers until you find a node which is the right child of its parent. That parent is the inorder predecessor.
Click to reveal answer
intermediate
Why is the inorder predecessor important in BST operations?
It helps in operations like deletion of a node with two children by replacing the node with its inorder predecessor to maintain BST properties.
Click to reveal answer
advanced
In Rust, what is a safe way to traverse to find the inorder predecessor in a BST?
Use recursive or iterative traversal with references or smart pointers (like Box or Rc) to safely navigate nodes, avoiding unsafe code and null pointers.
Click to reveal answer
What is the inorder predecessor of a node with no left child in a BST?
AThe parent node where the current node is in the right subtree
BThe root node of the BST
CThe leftmost node in its left subtree
DThe rightmost node in its right subtree
✗ Incorrect
If the node has no left subtree, the inorder predecessor is found by moving up to the parent where the node is in the right subtree.
Which node is the inorder predecessor of a node with a left subtree?
AThe root node
BThe leftmost node in the right subtree
CThe parent node
DThe rightmost node in the left subtree
✗ Incorrect
The inorder predecessor is the maximum node in the left subtree, which is the rightmost node there.
Why do we use the inorder predecessor during deletion of a node with two children in a BST?
ATo replace the node with a larger value and maintain BST order
BTo replace the node with a smaller value and maintain BST order
CTo delete the entire left subtree
DTo delete the entire right subtree
✗ Incorrect
Replacing with the inorder predecessor (largest smaller node) keeps the BST property intact after deletion.
In Rust, which pointer type is commonly used to represent BST nodes safely?
ABox or Rc smart pointers
BNull pointers
CRaw pointers (*)
DUnsafe pointers
✗ Incorrect
Box and Rc are safe smart pointers used in Rust to manage ownership and references in BST nodes.
What traversal order is used to define the inorder predecessor?
APreorder traversal
BPostorder traversal
CInorder traversal
DLevel order traversal
✗ Incorrect
The inorder predecessor is defined based on the inorder traversal order of the BST.
Explain how to find the inorder predecessor of a node in a BST with and without a left subtree.
Think about the inorder traversal sequence and how nodes relate to each other.
You got /2 concepts.
Describe why the inorder predecessor is useful in BST node deletion and how it helps maintain BST properties.
Consider what happens when you remove a node with two children.
You got /3 concepts.
Practice
(1/5)
1. What is the inorder predecessor of a node in a Binary Search Tree (BST)?
easy
A. The node with the largest value smaller than the given node
B. The node with the smallest value larger than the given node
C. The left child of the given node
D. The right child of the given node
Solution
Step 1: Understand BST property
In a BST, left subtree nodes are smaller and right subtree nodes are larger than the current node.
Step 2: Define inorder predecessor
The inorder predecessor is the node visited just before the current node in an 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 A
Quick Check:
Inorder predecessor = largest smaller value [OK]
Hint: Inorder predecessor is largest smaller node [OK]
Common Mistakes:
Confusing predecessor with successor
Choosing child nodes directly without checking values
Thinking predecessor is always left child
2. Which Rust code snippet correctly finds the inorder predecessor of a node with a left subtree in a BST?
easy
A. let pred = node.right.clone();
B. let mut pred = node.right.as_ref(); while let Some(left) = pred.unwrap().left.as_ref() { pred = Some(left); }
C. let mut pred = node.left.as_ref(); while let Some(right) = pred.unwrap().right.as_ref() { pred = Some(right); }
D. let pred = node.left.clone();
Solution
Step 1: Identify left subtree traversal
The inorder predecessor is the rightmost node in the left subtree, so start from node.left.
Step 2: Traverse to rightmost node
Keep moving to the right child until no more right child exists to find the largest node in left subtree.
Final Answer:
let mut pred = node.left.as_ref(); while let Some(right) = pred.unwrap().right.as_ref() { pred = Some(right); } -> Option C
Quick Check:
Traverse left subtree rightmost node = let mut pred = node.left.as_ref(); while let Some(right) = pred.unwrap().right.as_ref() { pred = Some(right); } [OK]
Hint: Go left once, then right as far as possible [OK]
Common Mistakes:
Starting from right subtree instead of left
Not looping to the rightmost node
Using clone instead of reference traversal
3. Given the BST below and node value 15, what is the inorder predecessor?
20
/ \
10 30
\ \
15 40
medium
A. 30
B. 15
C. 20
D. 10
Solution
Step 1: Locate node 15 and its left subtree
Node 15 has no left child, so we look for the ancestor smaller than 15.
Step 2: Find largest ancestor smaller than 15
10 is the parent of 15 and smaller than 15, so 10 is the inorder predecessor.
Final Answer:
10 -> Option D
Quick Check:
Largest smaller ancestor = 10 [OK]
Hint: If no left child, go up to smaller ancestor [OK]
Common Mistakes:
Choosing node itself as predecessor
Choosing larger ancestor incorrectly
Ignoring no left subtree case
4. Identify the bug in this Rust function to find the inorder predecessor of a BST node:
fn inorder_predecessor(node: &Option) -> Option<i32> {
let mut current = node.as_ref()?.left.as_ref();
while current?.right.is_some() {
current = current?.right.as_ref();
}
current.map(|n| n.val)
}
medium
A. Using '?' operator on Option without handling None case
B. Starting from node.right instead of node.left
C. Returning node.val instead of predecessor value
D. Not checking if node has left child before traversal
Solution
Step 1: Analyze use of '?' operator in loop condition
The '?' operator unwraps Option or returns None; using it inside while condition causes panic if None.
Step 2: Identify safe way to traverse Option references
Must use pattern matching or if let to safely unwrap Options instead of '?' in loop condition.
Final Answer:
Using '?' operator on Option without handling None case -> Option A
Quick Check:
Unsafe '?' in loop condition causes panic [OK]
Hint: Avoid '?' in loop conditions on Option [OK]
Common Mistakes:
Using '?' inside loops causing runtime panic
Ignoring None cases in Option traversal
Confusing left and right subtree
5. You want to find the inorder predecessor of a node in a BST that has no left child. Which approach correctly finds it?
hard
A. Return the rightmost node in the right subtree
B. Traverse up the tree to find the nearest ancestor whose right child is also an ancestor of the node
C. Return the leftmost node in the right subtree
D. Return the root node always
Solution
Step 1: Understand no left child case
If node has no left child, predecessor is not in left subtree but among ancestors.
Step 2: Find nearest ancestor where node is in right subtree
Traverse up until you find an ancestor whose right child is also an ancestor of the node; that ancestor is the predecessor.
Final Answer:
Traverse up the tree to find the nearest ancestor whose right child is also an ancestor of the node -> Option B
Quick Check:
No left child -> find right-side ancestor [OK]
Hint: Go up to ancestor where node is in right subtree [OK]
Common Mistakes:
Returning nodes from right subtree incorrectly
Always returning root node
Ignoring ancestor traversal
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.