DSA Notes
Understand hash tables from the ground up — key-value mapping, hash functions, O(1) average-case lookup, load factor, and why hashing is ubiquitous in computing.
What is Hashing?
Hashing is a technique that maps data of arbitrary size to fixed-size values (hash codes), enabling near-constant-time insertion, deletion, and lookup. A hash table (also called hash map or dictionary) uses a hash function to compute an index into an array of buckets, where the desired value can be found.
Think of it like a library with a magical catalog system: instead of searching through every shelf, you compute a formula from the book title that tells you exactly which shelf to check. Most of the time, you find the book immediately.
The Hash Table Structure
| Key | hash_function(key) → index → bucket[index] → value |
| hash("apple") = 3 | table[3] = "apple: red fruit" |
| hash("banana") = 5 | table[5] = "banana: yellow fruit" |
| hash("cherry") = 1 | table[1] = "cherry: small red fruit" |
| table | [_, "cherry:...", _, "apple:...", _, "banana:...", _] |
Core Operations and Their Complexity
| Operation | Average Case | Worst Case | Notes |
|---|---|---|---|
| Insert | O(1) | O(n) | Worst case: all keys hash to same index |
| Search | O(1) | O(n) | Average assumes good hash function |
| Delete | O(1) | O(n) | Same reasoning as search |
The "O(1) average" depends on two things:
- A good hash function that distributes keys uniformly
- A load factor that stays below a threshold
How a Hash Table Works
Insertion
- Compute
index = hash(key) % table_size - Store the (key, value) pair at
table[index] - If there is already something at that index (collision), handle it (chaining or probing)
Lookup
- Compute
index = hash(key) % table_size - Go to
table[index] - If the key matches, return the value
- If collision handling was used, search through the chain/probe sequence
Deletion
- Find the key (same as lookup)
- Remove it from the bucket/slot
- Handle any structural cleanup (e.g., tombstone markers in open addressing)
Load Factor
The load factor α = n/m, where n = number of stored elements and m = table size.
- α < 0.7 → good performance for open addressing
- α < 1.0 → reasonable for chaining
- α > 1.0 → guaranteed collisions (only possible with chaining)
When α exceeds a threshold, we resize (typically double) the table and rehash all elements. This keeps operations at O(1) amortized.
# Load factor calculation
n = 15 # elements stored
m = 20 # table size
alpha = n / m # 0.75
# Time to resize! Most implementations resize at α = 0.75
# New table: m = 40, rehash all 15 elements
# New α = 15/40 = 0.375 — plenty of roomPython Implementation from Scratch
C++ Implementation
Why Hashing is Everywhere
Hash tables are arguably the most important data structure in practical computing:
- Python dict, JavaScript object/Map, Java HashMap, C++ unordered_map — all hash tables
- Database indexing: Hash indexes for equality queries
- Caching: Memcached, Redis use hashing for key-value storage
- Compilers: Symbol tables mapping variable names to metadata
- Networking: Hash tables for connection tracking, routing tables
- Deduplication: Detect duplicate files/records via hash comparison
- Load balancing: Consistent hashing distributes requests across servers
Hash Table vs Other Data Structures
| Structure | Search | Insert | Delete | Ordered? |
|---|---|---|---|---|
| Hash table | O(1) avg | O(1) avg | O(1) avg | No |
| BST (balanced) | O(log n) | O(log n) | O(log n) | Yes |
| Sorted array | O(log n) | O(n) | O(n) | Yes |
| Linked list | O(n) | O(1) | O(n) | No |
Choose hash tables when you need fast lookup/insert and do not need ordering. Choose BSTs when you need range queries or sorted traversal.
Common Pitfalls
- Bad hash function: If many keys map to the same bucket, performance degrades to O(n)
- Not handling resize: Without dynamic resizing, load factor grows unbounded
- Mutable keys: If a key changes after insertion, its hash changes and lookup fails
- Hash flooding attacks: Adversarial inputs causing worst-case O(n) in web servers (mitigated by randomized hashing)
Key Takeaways
Hashing provides O(1) average-case operations by converting keys into array indices. The magic relies on good hash functions and controlled load factors. Hash tables are the default choice for key-value lookup in virtually every programming language and system. Understanding how they work internally — including collision handling and resizing — is essential for both interviews and systems design.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Hashing Fundamentals.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Data Structures & Algorithms topic.
Search Terms
data-structures-algorithms, data structures & algorithms, data, structures, algorithms, hashing, introduction, hashing fundamentals
Related Data Structures & Algorithms Topics