Why Trees Exist and What Linked Lists and Arrays Cannot Do in DSA C++ - Performance Analysis
We want to understand why trees are useful compared to linked lists and arrays.
What problems do trees solve that others cannot do efficiently?
Analyze the time complexity of searching for a value in different data structures.
// Searching in an array
bool searchArray(int arr[], int n, int target) {
for (int i = 0; i < n; i++) {
if (arr[i] == target) return true;
}
return false;
}
// Searching in a binary search tree
bool searchBST(Node* root, int target) {
if (!root) return false;
if (root->val == target) return true;
if (target < root->val) return searchBST(root->left, target);
else return searchBST(root->right, target);
}
This code shows searching in an array and in a binary search tree.
Look at what repeats when searching.
- Primary operation: Checking each element in array or moving down tree nodes.
- How many times: Array checks up to n times; BST checks up to height of tree times.
As input size grows, array search checks more elements one by one.
| Input Size (n) | Array Checks | BST Checks (height) |
|---|---|---|
| 10 | Up to 10 | Up to 4 |
| 100 | Up to 100 | Up to 7 |
| 1000 | Up to 1000 | Up to 10 |
Array search grows linearly; BST search grows much slower, roughly with tree height.
Time Complexity: O(n) for array, O(log n) for balanced BST
This means searching in arrays takes longer as size grows, but trees can find items faster by skipping parts.
[X] Wrong: "Trees are always faster than arrays for searching."
[OK] Correct: If the tree is not balanced, search can be as slow as array search.
Understanding why trees exist helps you explain data choices clearly and shows you know how to pick the right tool for the job.
"What if the binary search tree is unbalanced and looks like a linked list? How does that affect time complexity?"
Practice
Solution
Step 1: Understand the limitation of arrays and linked lists
Arrays and linked lists store data in a linear order, which makes it hard to represent hierarchical or branching relationships.Step 2: Identify the unique feature of trees
Trees allow each element to have multiple children, representing hierarchical data like family trees or file systems.Final Answer:
Trees represent hierarchical relationships which arrays and linked lists cannot -> Option DQuick Check:
Hierarchical data needs trees = Because trees can represent hierarchical relationships which arrays and linked lists cannot [OK]
- Thinking trees always use less memory
- Assuming trees are simpler to implement
- Believing trees always have faster access
Solution
Step 1: Understand pointer usage in tree nodes
Each child node should be a pointer to allow dynamic linking and avoid infinite size.Step 2: Check each option for correct pointer usage
struct Node { int data; Node* left; Node* right; }; uses pointers for both left and right child nodes, which is correct. Options A, B, and C mix pointers and objects incorrectly.Final Answer:
struct Node { int data; Node* left; Node* right; }; -> Option AQuick Check:
Child nodes must be pointers = struct Node { int data; Node* left; Node* right; }; [OK]
- Declaring child nodes as objects causing infinite recursion
- Mixing pointers and objects incorrectly
- Forgetting to use pointers for children
struct Node {
int data;
Node* left;
Node* right;
Node(int val) : data(val), left(nullptr), right(nullptr) {}
};
Node* root = new Node(10);
root->left = new Node(5);
root->right = new Node(15);
root->left->left = new Node(3);
std::cout << root->left->left->data << std::endl;
What will be the output?Solution
Step 1: Trace the tree construction
Root node has value 10. Left child is 5, right child is 15. Left child's left child is 3.Step 2: Identify the printed value
The code prints root->left->left->data, which is the left child of 5, value 3.Final Answer:
3 -> Option BQuick Check:
root->left->left = 3 [OK]
- Confusing left and right children
- Printing root->left->data instead of left->left
- Assuming default values instead of assigned
struct Node {
int data;
Node left;
Node right;
Node(int val) : data(val) {}
};
int main() {
Node root(10);
return 0;
}Solution
Step 1: Analyze struct member types
Node contains members left and right of type Node (not pointers), causing recursive embedding.Step 2: Understand compilation error cause
This recursive embedding causes infinite size, which is not allowed by the compiler.Final Answer:
Error because Node contains objects of its own type causing infinite size -> Option CQuick Check:
Struct with own type members causes infinite size error [OK]
- Thinking constructor syntax is wrong
- Assuming missing initialization causes error
- Believing code compiles fine
Solution
Step 1: Understand the organizational chart structure
Each manager can have multiple direct reports, which is a hierarchical relationship with branching.Step 2: Compare data structures for representing hierarchy
Arrays and linked lists are linear and cannot naturally represent multiple children per node, but trees can.Final Answer:
Trees allow multiple children per node, representing multiple reports naturally -> Option AQuick Check:
Multiple children per node = trees [OK]
- Thinking arrays cannot store objects
- Believing linked lists cannot store any hierarchy
- Assuming trees always use less memory
Ready to prove it?
Pass the test and this pattern moves unknown
