Hash tables: average O(1) insert, erase and lookup, no ordering. The workhorse for frequency counts, “seen before?” checks and caches.
Usage
#include <iostream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
int main() {
std::vector<int> nums{2, 7, 11, 15};
int target = 18;
std::unordered_map<int, int> seen; // value → index
for (int i = 0; i < static_cast<int>(nums.size()); ++i) {
if (auto it = seen.find(target - nums[i]); it != seen.end())
std::cout << "two-sum: " << it->second << ',' << i << '\n';
seen[nums[i]] = i;
}
std::unordered_set<std::string> visited;
for (std::string city : {"paris", "rome", "paris"})
if (!visited.insert(city).second) std::cout << "repeat: " << city << '\n';
std::cout << visited.size() << ' ' << visited.contains("rome") << '\n';
}two-sum: 1,2
repeat: paris
2 1Buckets, load factor, rehashing
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<int, int> m;
m.reserve(1000); // pre-size buckets: avoids rehashing while filling
for (int i = 0; i < 1000; ++i) m[i] = i * i;
std::cout << m.size() << ' ' << (m.bucket_count() >= 1000) << ' ' << (m.load_factor() <= m.max_load_factor()) << '\n';
std::cout << m.max_load_factor() << '\n'; // default 1.0: rehash when size > buckets
}1000 1 1
1Hashing your own type
#include <cstddef>
#include <functional>
#include <iostream>
#include <unordered_set>
struct Point {
int x, y;
bool operator==(const Point&) const = default; // needed for collisions
};
struct PointHash {
std::size_t operator()(const Point& p) const noexcept {
std::size_t h1 = std::hash<int>{}(p.x), h2 = std::hash<int>{}(p.y);
return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2)); // hash_combine
}
};
int main() {
std::unordered_set<Point, PointHash> cells{{0, 0}, {1, 2}, {0, 0}};
std::cout << cells.size() << ' ' << cells.count({1, 2}) << '\n';
}2 1unordered_map | map | |
|---|---|---|
| Structure | Hash table (buckets of nodes) | Red-black tree |
| Lookup | O(1) avg, O(n) worst | O(log n) always |
| Order | None | Sorted by key |
| Key needs | std::hash<K> + == | < |
| Memory | Higher (buckets) | 3 pointers + colour per node |
How does an unordered_map handle collisions?