Why BST Over Plain Binary Tree in DSA Rust - Performance Analysis
We want to understand why a Binary Search Tree (BST) is faster than a plain binary tree for searching data.
How does the structure affect the time it takes to find a value?
Analyze the time complexity of searching for a value in these two tree types.
// Plain binary tree search (no order)
fn search_plain_tree(node: &Option>, target: i32) -> bool {
if let Some(n) = node {
if n.value == target {
return true;
}
return search_plain_tree(&n.left, target) || search_plain_tree(&n.right, target);
}
false
}
// BST search (ordered)
fn search_bst(node: &Option>, target: i32) -> bool {
if let Some(n) = node {
if n.value == target {
return true;
} else if target < n.value {
return search_bst(&n.left, target);
} else {
return search_bst(&n.right, target);
}
}
false
}
The first searches every node until it finds the target or ends. The second uses order to skip parts.
Look at what repeats as the tree grows.
- Primary operation: Checking nodes one by one.
- How many times: Plain tree may check all nodes; BST checks nodes along one path.
As the number of nodes (n) grows, how many checks happen?
| Input Size (n) | Approx. Operations Plain Tree | Approx. Operations BST |
|---|---|---|
| 10 | Up to 10 checks | About 4 checks (height) |
| 100 | Up to 100 checks | About 7 checks |
| 1000 | Up to 1000 checks | About 10 checks |
Pattern observation: Plain tree checks grow directly with n; BST checks grow slowly with tree height (log n).
Time Complexity: O(n) for plain tree, O(log n) for balanced BST
BST lets us find values much faster by skipping large parts of the tree using order.
[X] Wrong: "A BST always searches faster than a plain tree no matter what."
[OK] Correct: If the BST is not balanced, it can become like a list, making search time similar to plain tree.
Understanding why BSTs are faster helps you explain data structure choices clearly and shows you know how structure affects speed.
"What if the BST becomes unbalanced and looks like a linked list? How does that change the search time complexity?"
Practice
Solution
Step 1: Understand the structure difference
A plain Binary Tree has no order, so searching requires checking many nodes.Step 2: Analyze BST property
BST keeps nodes sorted: left child smaller, right child larger, enabling binary search.Final Answer:
Because BST keeps elements in sorted order, allowing faster search -> Option DQuick Check:
Sorted structure = faster search [OK]
- Thinking BST uses less memory
- Confusing number of children per node
- Assuming BST has no pointers
Solution
Step 1: Understand Rust ownership for trees
Nodes must use Option for left and right to allow null and ownership.Step 2: Check each option
struct Node { value: i32, left: Option, right: Option } uses Option, correct for nullable child nodes. Others miss Option or use references incorrectly.Final Answer:
struct Node { value: i32, left: Option, right: Option } -> Option BQuick Check:
Nullable boxed children = struct Node { value: i32, left: Option, right: Option } [OK]
- Omitting Option causing no null children
- Using references without lifetimes
- Using Box without Option causing no empty child
struct Node { value: i32, left: Option, right: Option }
fn insert(root: &mut Option, val: i32) {
if let Some(node) = root {
if val < node.value {
insert(&mut node.left, val);
} else {
insert(&mut node.right, val);
}
} else {
*root = Some(Box::new(Node { value: val, left: None, right: None }));
}
}
fn inorder(root: &Option, vals: &mut Vec<i32>) {
if let Some(node) = root {
inorder(&node.left, vals);
vals.push(node.value);
inorder(&node.right, vals);
}
}
fn main() {
let mut root = None;
insert(&mut root, 10);
insert(&mut root, 5);
insert(&mut root, 15);
insert(&mut root, 7);
let mut result = Vec::new();
inorder(&root, &mut result);
println!("{:?}", result);
}Solution
Step 1: Insert values into BST
Insert 10 as root, 5 to left, 15 to right, 7 to right of 5.Step 2: Perform in-order traversal
In-order visits left, root, right: nodes visited in order 5, 7, 10, 15.Final Answer:
[5, 7, 10, 15] -> Option AQuick Check:
In-order traversal = sorted values [OK]
- Confusing traversal order
- Inserting nodes incorrectly
- Misreading left/right child placement
fn insert(root: &Option, val: i32) {
if let Some(node) = root {
if val < node.value {
insert(&node.left, val);
} else {
insert(&node.right, val);
}
} else {
*root = Some(Box::new(Node { value: val, left: None, right: None }));
}
}Solution
Step 1: Check parameter mutability
Function takes `root` as immutable reference `&Option`, so cannot modify it.Step 2: Identify assignment error
Line `*root = Some(...)` tries to assign through immutable reference, causing compile error.Final Answer:
Cannot assign to `*root` because `root` is an immutable reference -> Option CQuick Check:
Mutable reference needed for assignment [OK]
- Using & instead of &mut for mutable access
- Ignoring compiler error messages
- Assuming recursive calls cause stack overflow here
Solution
Step 1: Compare data organization
BST keeps nodes sorted, unlike plain Binary Tree which has no order.Step 2: Analyze operation time complexity
Balanced BST operations (search, insert, delete) take O(log n) on average due to tree height.Final Answer:
BST keeps data sorted, enabling O(log n) average time for search, insert, and delete -> Option AQuick Check:
Sorted structure + balanced height = O(log n) [OK]
- Assuming O(1) time for BST operations
- Confusing plain Binary Tree with BST
- Thinking BST nodes have multiple children
Ready to prove it?
Pass the test and this pattern moves unknown
