Handling Collisions in Hash Tables
A hash table stores key/value pairs in an array and uses the key to find where a pair is stored, avoiding a scan through unrelated items when the table works well.
Try it: How a dict Stores Keys
How a dictionary turns a key into a slot with a hash, what happens on a collision, why deleted keys leave a marker, and why the table grows.
How it works
- hash(key) gives a number; hash % table size gives the key's home slot.
- If that slot is taken by another key (a collision), probe the next slot.
- Deleting leaves a DELETED marker so lookups keep probing past it.
- When more than 2/3 of the slots are used, the table doubles and every key is re-inserted.
Default run (5 steps): A dict with 3 keys in 8 slots. Choose an operation. Example: d["mango"] = 5. … Done. 4 keys in 8 slots.
Simplified: Uses a small educational hash (Python's real string hash is randomised per run) and simple linear probing; CPython's probe order is more elaborate.
Loading the simulation…
Finding a Record Without Scanning Everything
Imagine you keep a list of student records, and each record is tied to a student ID. If someone asks for the record of a particular ID, the simplest approach is to start at the beginning of the list and check each record until you find a match. That approach works, but the time it takes grows as the list grows. A hash table is a structure designed to answer the question, given a key, without that long scan.
What do you think happens?
Suppose every key is a whole number from 0 to 99 and you have an array of 100 slots. The pair for key 42 is stored in slot 42. How many records must you check to find the pair for key 42?
Reveal answer
None. You read slot 42 directly, so no scanning is needed.
When the key itself determines the slot, the lookup goes straight to the location instead of walking through unrelated items. Hash tables try to get this same benefit for keys that are not small whole numbers.
What Other Lookup Methods Cost
In an unsorted list you may have to look at many unrelated items before reaching the right one. In a binary sort tree you follow a path from the root downward. A hash table tries to remove that searching entirely by letting the key itself point to a location. The source describes this as going directly to the place where the item is stored, with the caveat that this is close to true only when the hash table is working properly. Keeping that caveat in mind matters, because collisions are the reason it is only close to true.
Why Direct Indexing Breaks Down
Suppose every key were a whole number from 0 to 99. You could reserve an array of 100 slots and store each pair in the slot whose index equals its key. Finding a pair would require no search at all. The pair for key 42 would sit in slot 42, and you would simply read that slot.
This idea breaks down quickly for realistic keys. An int can take a very large number of values, so an array with one slot for every possible int would be enormous, even if you only plan to store a few thousand items. If keys are strings of arbitrary length, the number of possible keys has no limit, and one slot per key cannot be built at all. The direct-indexing idea is good, but the array has to be much smaller than the set of possible keys. That tension is what hash tables resolve.
Roles of the Key, Hash Function, Hash Code, and Index
A hash table stores its data in an array, but the array index for a key is not the key itself. Instead, the index is computed from the key. A hash function does this computing. The number a key produces this way is called its hash code. A hash code is therefore the array index where that key is stored.
The hash function is the only piece that knows how a key maps to a position. The rest of the table never has to inspect the other stored items to find the right one. In this example the key cat and the hash code 7 are illustrative values chosen to show the chain, not outputs of any particular hash function.
Tracing a Lookup Through the Chain
Looking up the pair for the key cat
A hash table holds a pair for the key cat. Using the hash function described above, which array location does a lookup visit, and how many other stored items does it need to inspect?
- 1Start with the key
The lookup begins with the key cat, the only thing the caller supplies.
- 2Pass the key through the hash function
The hash function computes a number from cat. In this illustration it produces the hash code 7.
- 3Use the hash code as the index
The hash code is the array index, so the lookup goes straight to slot 7.
- 4Check what the location holds
If slot 7 holds only the pair for cat, the lookup is finished with no inspection of other items.
The lookup visits one array location and inspects no unrelated stored items.
Because the lookup depends only on the key, the same key always produces the same hash code and so the same array location. That repeatability is what lets you find a pair again later without searching for it.
When Two Keys Land on the Same Slot
The array has fewer locations than there are possible keys, so two different keys can produce the same hash code. When that happens, both keys want the same array location. This situation is called a collision. A collision is not an error. A hash table cannot reject a key simply because another key already produced the same hash code. It has to be able to store both in some reasonable way.
Keeping Both Pairs in One Location
The approach described for the Java style of hash table is to let each array location hold a linked list of key/value pairs. The list may be empty. When two items share a hash code, they both belong to the same linked list at that location. The hash code still tells you the array location, but that location may now hold several pairs, so you must check the keys in that list to find the one you want.
The values 4 and 9 in the diagram are illustrative. To find the pair for dog in slot 3, the lookup checks the key of the first entry, sees cat, moves to the next entry, and finds dog. The extra checking stays inside a single location. The source notes that if the hash table is working properly, that checking stays small, which is why the direct-access idea is described as close to true rather than exactly true.
Mistakes Beginners Make with Collisions
Common mistake Assuming the key is the array index
What it looks likeStoring the pair for cat directly at a slot chosen by its letters without any hash function.
Why it failsThe index for a key is not the key itself. A hash function computes a hash code from the key, and that hash code is the index.
Do this insteadPass the key through the hash function first, then use the resulting hash code as the array index.
Common mistake Treating a collision as an error
What it looks likeRejecting the key dog because slot 3 is already occupied by cat.
Why it failsThe array has fewer locations than possible keys, so collisions are expected and are not errors.
Do this insteadStore both pairs in the same location, for example in a linked list, and distinguish them by checking their keys.
Common mistake Assuming a location holds only one pair
What it looks likeReading slot 3 and returning the first value without comparing keys.
Why it failsA location may hold several pairs after a collision, so the value returned could belong to a different key.
Do this insteadCompare the key you want against each key in the list at that location before returning a value.
Common mistake Believing the same key can produce different hash codes at different times, which would make lookups unreliable
Practice Tracing a Collision
A hash table uses the hash function described in this article. The keys cat and dog both produce hash code 3, and the key bird produces hash code 5. Describe where the pair for dog is stored, what a lookup for dog must check, and why the lookup for bird does not need to check cat or dog.
Hints
- Start by asking which array location the hash code 3 points to.
- Ask whether the location for hash code 3 holds one pair or a list of pairs.
- Ask which location bird's hash code points to, and whether that location shares any entries with cat or dog.
Key Takeaways
- A hash table stores key/value pairs in an array and uses the key to find where a pair is stored, avoiding a scan through unrelated items when the table works well.
- The index for a key is not the key itself. A hash function computes a hash code from the key, and that hash code is the array index.
- The array has fewer locations than possible keys, so two keys can produce the same hash code. This collision is expected and is not an error.
- In the Java style described in the source, each array location holds a linked list of pairs, so colliding keys share a location and are told apart by comparing their keys during lookup.