A technique used to map data of an arbitrary size to data of a fixed size. The values returned by a hash function are called hash values, hash codes, digests, or simply hashes. The values are used to index a fixed-size table called a hash table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
{
"status": "Initializing hash table",
"size": 10
}Overview
A hash table stores key-value pairs in an array of buckets. A hash function turns each key into a bucket index, so a lookup can jump straight to the right bucket instead of searching the whole collection. When two keys land in the same bucket — a collision — this implementation uses separate chaining: each bucket holds a small list of entries.
The hash function here is hash = (hash + charCode(key[i]) * i) % 10, with 10 buckets. It is deliberately simple so you can check it by hand, but it has a flaw worth noticing: the first character is multiplied by i = 0, so it never affects the result. 'cat' and 'bat' always land in the same bucket.
The default input inserts 15 fruits into 10 buckets, a load factor of 1.5, which guarantees collisions. In the dry run you can see six of them; bucket 8 ends up holding grape, peach and kiwi. Looking up 'grape' hashes to bucket 8 and finds it as the first entry in that chain.
Step by step
- Compute
index = hash(key). - To insert: if the key already exists in
table[index], update its value; otherwise append the pair to that bucket's list. - To look up: compute the same index and scan that bucket's list for the key.
- To delete: find the entry in its bucket and remove it from the list.
- In production, resize (rehash into a larger table) when the load factor passes a threshold such as 0.75.
Complexity
| Case | Cost | Why |
|---|---|---|
| Insert / lookup / delete (average) | O(1) | With a good hash and a bounded load factor, chains stay short. |
| Insert / lookup / delete (worst) | O(n) | If every key collides, one bucket holds everything. |
| Resize | O(n) | Occasional; amortised O(1) per insert when the table doubles. |
| Space | O(n + m) | n entries plus m buckets. |
When to use it
- Fast membership tests and lookups: caches, symbol tables, de-duplication, counting frequencies.
- Many interview problems (Two Sum, Group Anagrams, LRU Cache) reduce to the right hash map.
- Joining or indexing data by a key when you never need it in sorted order.
Common mistakes
- Weak hash functions, like the one shown, cluster keys and destroy the O(1) average.
- Not resizing: a fixed 10-bucket table with 1,000 keys behaves like ten linked lists.
- Using mutable objects as keys and then changing them, so their hash no longer matches their bucket.
A dry run is the best way to check your understanding of Hashing: follow each row, predict the next one, and compare. The run below takes 88 steps in total. Steps that only re-print loop counters are left out so the decisions stand out. The Line column refers to the line numbers in the code listing above.
- Input
- apple,red;banana,yellow;grape,purple;orange,orange;mango,yellow;strawberry,red;peach,orange;lemon,yellow;lime,green;cherry,red;blueberry,blue;watermelon,green;pear,green;pineapple,yellow;kiwi,green
- Lookup key
- grape
- Result
- key = grape, status = Key found!, value = purple
| Step | Line | What happens |
|---|---|---|
| 1 | 1 | status = Initializing hash table, size = 10 |
| 2 | 14 | action = set, key = apple, value = red |
| 5 | 18 | key = apple, value = red, index = 4, status = Inserting new key-value pair |
| 6 | 20 | status = Finished inserting 'apple' |
| 7 | 14 | action = set, key = banana, value = yellow |
| 10 | 18 | key = banana, value = yellow, index = 3, status = Inserting new key-value pair |
| 11 | 20 | status = Finished inserting 'banana' |
| 12 | 14 | action = set, key = grape, value = purple |
| 15 | 18 | key = grape, value = purple, index = 8, status = Inserting new key-value pair |
| 16 | 20 | status = Finished inserting 'grape' |
| 17 | 14 | action = set, key = orange, value = orange |
| 20 | 18 | key = orange, value = orange, index = 5, status = Inserting new key-value pair |
| 21 | 20 | status = Finished inserting 'orange' |
| 22 | 14 | action = set, key = mango, value = yellow |
| 25 | 18 | key = mango, value = yellow, index = 0, status = Inserting new key-value pair |
| 26 | 20 | status = Finished inserting 'mango' |
| 27 | 14 | action = set, key = strawberry, value = red |
| 30 | 18 | key = strawberry, value = red, index = 6, status = Inserting new key-value pair |
| 31 | 20 | status = Finished inserting 'strawberry' |
| 32 | 14 | action = set, key = peach, value = orange |
| 35 | 17 | key = peach, value = orange, index = 8, status = Collision detected! |
| 36 | 18 | key = peach, value = orange, index = 8, status = Inserting new key-value pair |
| 37 | 20 | status = Finished inserting 'peach' |
| 38 | 14 | action = set, key = lemon, value = yellow |
| 41 | 18 | key = lemon, value = yellow, index = 2, status = Inserting new key-value pair |
| 42 | 20 | status = Finished inserting 'lemon' |
| 43 | 14 | action = set, key = lime, value = green |
| 46 | 17 | key = lime, value = green, index = 6, status = Collision detected! |
| 47 | 18 | key = lime, value = green, index = 6, status = Inserting new key-value pair |
| 48 | 20 | status = Finished inserting 'lime' |
| 49 | 14 | action = set, key = cherry, value = red |
| 52 | 18 | key = cherry, value = red, index = 9, status = Inserting new key-value pair |
| 53 | 20 | status = Finished inserting 'cherry' |
| 54 | 14 | action = set, key = blueberry, value = blue |
| 57 | 17 | key = blueberry, value = blue, index = 2, status = Collision detected! |
| 58 | 18 | key = blueberry, value = blue, index = 2, status = Inserting new key-value pair |
| 59 | 20 | status = Finished inserting 'blueberry' |
| 60 | 14 | action = set, key = watermelon, value = green |
| 63 | 17 | key = watermelon, value = green, index = 3, status = Collision detected! |
| 64 | 18 | key = watermelon, value = green, index = 3, status = Inserting new key-value pair |
The remaining 16 key steps follow the same pattern. Press play in the visualizer to watch every step through to the result.