Sets
Set
Internally becomes:
Stores unique elements
Automatically sorted
Implemented using a balanced BST (Red-Black Tree)
Order is determined by < (or a custom comparator)
Elements are immutable (you can’t modify them directly)
Why immutable? Because changing a value might break the tree ordering.
Operations on set
Lower and upper bound on set
Multiset
Stored as:
Same as set
Allows duplicates
Still sorted
Still tree-based
Set vs Multiset
Feature | set | multiset |
|---|---|---|
Duplicates | ❌ | ✅ |
Sorted | ✅ | ✅ |
count(x) | 0 or 1 | 0 to n |
erase(x) | removes one | removes all |
Erase one occurrence:
Unordered Set
Stored like:
Stores unique elements
No ordering
Implemented using a hash table
Average O(1) insert/find/erase
Worst-case O(n) if hashing goes badly
No lower_bound / upper_bound
Operations on unordered set
Hashing
Uses
std::hash<T>by defaultWorks for basic types
Custom types need a custom hash
Needs:
Custom hash
Or lambda hash
Summary
Operation | set / multiset | unordered_set |
|---|---|---|
Insert | O(log n) | O(1) avg |
Find | O(log n) | O(1) avg |
Erase | O(log n) | O(1) avg |
Order | Sorted | None |
Use set when:
You need sorted unique elements
You need lower_bound / upper_bound
Predictable performance matters
Use multiset when:
You need sorted data with duplicates
Counting occurrences with order
Use unordered_set when:
Order doesn’t matter
You want fast lookup