Unordered Containers
Master hash-based unordered_set and unordered_map for O(1) average-case performance when order doesn't matter
Discover unordered containers that trade sorted order for blazing-fast O(1) average-case performance using hash tables.
A Simple Example
#include <iostream>
#include <unordered_set>
#include <unordered_map>
#include <string>
int main() {
// unordered_set - unique elements, NO sorting
std::unordered_set<int> numbers{5, 2, 8, 2, 1, 9};
std::cout << "Unordered set (no guaranteed order): ";
for (int num : numbers) {
std::cout << num << " "; // Order is unpredictable!
}
std::cout << "\n";
// Fast O(1) average lookup
if (numbers.find(8) != numbers.end()) {
std::cout << "Found 8 in O(1) average time!" << "\n";
}
// unordered_map - key-value pairs, NO sorting
std::unordered_map<std::string, int> scores{
{"Alice", 95},
{"Bob", 87},
{"Charlie", 92}
};
// O(1) average access
std::cout << "Alice's score: " << scores["Alice"] << "\n";
// Insertion is O(1) average
scores["Diana"] = 88;
std::cout << "\nAll scores (no guaranteed order):" << "\n";
for (const auto& [name, score] : scores) {
std::cout << name << ": " << score << "\n";
}
return 0;
}
Breaking It Down
Hash Tables - The Secret Behind Speed
- What it is: Array-based structure where hash function maps keys to indices
- O(1) average-case insertion, deletion, and lookup
- No ordering - elements arranged by hash value, not natural order
- Use when: Speed matters more than order
unordered_set vs set
- unordered_set: O(1) average operations, no order guarantee
- set: O(log n) operations, sorted order maintained
- unordered_set uses more memory for hash table
- Remember: Choose based on whether you need speed or order
unordered_map vs map
- unordered_map: O(1) average for find/insert, no key ordering
- map: O(log n) for operations, keys always sorted
- unordered_map is faster for large datasets when order doesn't matter
- Remember: Can't use lower_bound/upper_bound on unordered_map
Hash Collisions and Worst Case
- What it is: When different keys hash to same index
- Worst case: O(n) when all keys collide (rare with good hash function)
- Good hash functions distribute keys evenly
- Remember: Average case O(1) is what matters in practice
Why This Matters
- Unordered containers trade sorted order for speed.
- When you need fast lookups and don't care about order, unordered_map and unordered_set provide O(1) average performance instead of O(log n).
- This can be the difference between a responsive application and one that feels sluggish with large datasets.
Critical Insight
Hash tables are like a library where books are placed based on the first letter of their title - you can find any book instantly by going to the right section (O(1)), but you can't efficiently browse all books in alphabetical order.
Ordered containers (set/map) are like a sorted shelf - finding takes longer (O(log n)) but you can browse in order.
Choose based on what you need: speed or order!
Best Practices
Default to unordered containers for lookups: When you only need fast find/insert/delete and don't need order, use unordered versions.
Use ordered containers when order matters: If you need sorted iteration or range queries, use set/map.
Reserve capacity for known sizes: Call reserve() if you know the size upfront to avoid rehashing.
Understand hash requirements: Custom types need a hash function to be used in unordered containers.
Common Mistakes
Expecting order: Unordered containers don't maintain any order. Iteration order is unpredictable and can change.
Using with non-hashable types: Custom types need a hash function and equality operator to work with unordered containers.
Iterator invalidation: Rehashing (when load factor exceeds threshold) invalidates all iterators.
Debug Challenge
This code needs the fastest possible lookups and doesn't care about order. Click the highlighted line to optimize:
Quick Quiz
- What's the average time complexity of unordered_map::find()?
- When should you use map instead of unordered_map?
Practice Playground
Time to try out what you just learned! Play with the example code below, experiment by making changes and running the code to deepen your understanding.
Output:
Error:
Lesson Progress
- Fix This Code
- Quick Quiz
- Practice Playground - run once