Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 56

Collision Resolution Techniques and Load Factor Analysis

Recommended resources

Welcome to the final lesson of the Data Structures module. We've journeyed from linear structures like arrays and linked lists to complex tree structures like AVL trees and heaps, each offering unique performance trade-offs. In our last session, we saw how heaps provide insertion and extraction of the highest-priority element, making them ideal for priority queues.

Today, we switch gears to a technique that aims for the ultimate speed: Hashing. The goal of hashing is to achieve average-case constant time, or , for search, insertion, and deletion. This makes it incredibly powerful for applications like symbol tables in compilers or indexing in databases. However, this speed comes with a challenge: collisions.

Your learning outcome for this lesson is to master the two primary strategies for resolving these collisions: separate chaining and open addressing (specifically linear and quadratic probing). We will also analyze how the load factor of a hash table critically impacts its performance, a concept frequently tested in GATE.

1. The Core Idea: Hashing and Collisions

At its heart, hashing is a simple idea. We use a hash function, , to compute an index in an array (called a hash table) for a given key . In an ideal world, every key would map to a unique index. For example, a common hash function is the division method: , where is the size of the hash table.

The problem arises when two different keys map to the same index. This is called a collision. For instance, if our table size and we want to store keys 6 and 26, both would map to index 6 ( and ). We can't store both in the same slot. How we handle this is the central topic of this lesson.

To start, let's solidify this foundational concept of hashing and collisions.

8.1 Hashing Techniques to Resolve Collision| Separate Chaining and Linear Probing | Data structure

This video from Jenny's Lectures CS IT provides an excellent introduction. It contrasts hashing with other search techniques and clearly illustrates what a collision is.

Watch the initial segment from the beginning. Focus on understanding why hashing promises O(1) search time and how the example with keys 6 and 26 demonstrates a collision.

All collision resolution techniques fall into two broad categories: Separate Chaining (also called closed addressing) and Open Addressing.


2. Strategy 1: Separate Chaining

Separate chaining is an intuitive and popular method for handling collisions. The idea is to not store the elements directly in the hash table slots. Instead, each slot in the table acts as a head pointer to a linked list. All keys that hash to the same index are simply added to that index's linked list.

  • Insertion: To insert a key, you compute its hash index and insert it into the linked list at that position. For insertion, you can simply add the new node at the head of the list.
  • Search/Deletion: To search for or delete a key, you compute its hash index, which directs you to the correct linked list. You then perform a standard linear search on that list to find or remove the element.

The performance of separate chaining is determined by the load factor, , defined as:

where is the number of keys stored and is the number of slots in the hash table. For separate chaining, it's perfectly acceptable for to be greater than 1.

The average length of a chain is . Therefore, the average time for an unsuccessful search is , and for a successful search, it's approximately . Assuming a good hash function that distributes keys uniformly, if we keep as a small constant (e.g., by making the table size proportional to the number of keys ), the average search time becomes .

Let's walk through a detailed example to see exactly how this works.

8.1 Hashing Techniques to Resolve Collision| Separate Chaining and Linear Probing | Data structure

The same video continues with a clear, step-by-step demonstration of inserting a series of keys into a hash table using separate chaining.

Watch the segment from this timestamp. Follow along as each key is hashed and placed. Pay close attention to what happens when collisions occur for keys 11, 13, 7, and 12, and see how the linked lists at indices 5, 9, and 7 are built up.


3. Strategy 2: Open Addressing

Open addressing takes a different approach. All keys are stored directly inside the hash table. If a collision occurs at index , we probe for another empty slot in the table according to a fixed rule.

For open addressing, the load factor must be less than or equal to 1. As gets close to 1, the table fills up, and finding an empty slot can become very slow.

The probe sequence is generated by a function of the form:

where is the initial hash function, is the probe attempt number (starting from ), and is the function that distinguishes the different open addressing techniques.

3.1. Linear Probing

This is the simplest form of open addressing. The probe function is . If the initial slot is occupied, we try , then , and so on, wrapping around the table if necessary, until we find an empty slot.

  • Problem: Primary Clustering: Linear probing suffers from a problem where long runs of occupied slots tend to build up. When a new key hashes to anywhere in this cluster, it has to traverse to the end of the cluster to be inserted, further lengthening it. This significantly degrades performance.
  • Deletion: Deletion is tricky. If we simply remove an element from a slot, it might break the "chain" for a subsequent probe sequence. For example, if we inserted keys A, B, C where A and B hashed to index 10 and C hashed to 11, B would be placed at 11 and C at 12. If we then delete B from slot 11, a search for C would fail, as the probe would stop at the now-empty slot 11. To solve this, we mark deleted slots with a special "tombstone" or "deleted" marker. A new element can be inserted into a deleted slot, but a search probe must continue past it.

Let's see how linear probing works, including the crucial detail of handling deletions.

Hashing | Set 3 (Open Addressing) | GeeksforGeeks

This video from GeeksforGeeks introduces open addressing and then dives into a clear example of linear probing for insertion, search, and deletion.

First, watch the brief introduction to open addressing from this segment. Then, watch the detailed explanation of linear probing from this section. Note how collisions for keys 18 and 62 are resolved. Most importantly, understand the logic for the search operation and why delete requires marking a slot as "deleted" rather than "empty".

3.2. Quadratic Probing

To alleviate the primary clustering problem of linear probing, we can use a non-linear probe sequence. In quadratic probing, the probe function is quadratic, typically . If the initial slot is occupied, we check , then , then , and so on.

  • Advantage: Keys that hash to the same location will not necessarily follow the same probe sequence if other keys have already occupied the primary probe slots. This helps mitigate primary clustering.
  • Disadvantage: It can lead to secondary clustering, where keys that hash to the same initial slot do follow the same alternative probe sequence. Also, it is not guaranteed to find an empty slot even if one exists, unless the table size is a prime number and the load factor is kept below 0.5.

Hashing | Set 3 (Open Addressing) | GeeksforGeeks

The same GeeksforGeeks video continues by applying quadratic probing to the same set of keys, making it easy to compare with linear probing.

Watch the section on quadratic probing from this segment. Observe how the collision for key 62 is resolved differently. Instead of being placed at index 9 (linearly next to 18), it jumps to index 0 because of the i^2 term (h_2 = (7+2^2) \pmod{11} = 0).

3.3. Double Hashing (Briefly)

Double hashing is one of the best open addressing methods available. It uses a second hash function, , to determine the step size for the probe sequence: .

This means that keys hashing to the same initial location will likely have different probe sequences because their step sizes (determined by ) will be different. This effectively eliminates both primary and secondary clustering. The main drawback is the extra computational cost of a second hash function. The syllabus only requires you to be aware of it, so we won't go into a full example.


4. Performance Analysis and Comparison

The performance of open addressing is highly sensitive to the load factor . The expected number of probes for an operation is approximately . You can see that as approaches 1 (the table becomes full), the denominator approaches 0, and the number of probes skyrockets. This is in contrast to separate chaining, where performance degrades more gracefully as .

Let's summarize the trade-offs between these methods.

Hashing | Set 3 (Open Addressing) | GeeksforGeeks

This final clip from GeeksforGeeks compares the probing methods and formally states the complexity in terms of the load factor.

First, watch the comparison of linear probing, quadratic probing, and double hashing on factors like cache performance and clustering. Then, watch the segment on complexity, which introduces the formal relationship between performance and the load factor \alpha.

Here is a summary table for your quick reference:

Technique Space Usage Clustering Cache Performance Deletion
Separate Chaining Extra space for pointers None (chains grow) Poor (linked list nodes can be scattered) Simple
Linear Probing No extra space Primary Clustering (severe) Excellent (sequential access) Complex (requires tombstones)
Quadratic Probing No extra space Secondary Clustering (mild) Good Complex (requires tombstones)
Double Hashing No extra space None Poor (random access pattern) Complex (requires tombstones)

Conclusion

In this lesson, we explored hashing, a technique that provides the potential for average-time complexity for dictionary operations. We saw that this performance hinges on effectively managing collisions.

Key Takeaways:

  • Hashing maps keys to table indices; collisions occur when different keys map to the same index.
  • Separate Chaining resolves collisions by storing keys in linked lists at each index. Its performance, , degrades linearly with the load factor .
  • Open Addressing resolves collisions by probing for the next available slot within the table itself. Its performance is critically dependent on the load factor, approximately , and must be less than 1.
  • Linear Probing () is simple and cache-friendly but suffers from primary clustering.
  • Quadratic Probing () mitigates primary clustering but can cause secondary clustering.
  • Load Factor () is the single most important parameter for analyzing hash table performance. For GATE, you must be comfortable with how it affects both chaining and open addressing.

This lesson concludes our module on Data Structures. We've built a solid foundation that will be indispensable for the next, and most heavily-weighted, part of your preparation: Algorithms. In our upcoming lessons, we will start by formalizing the language of algorithm analysis with Asymptotic Notation, mastering Big-O, Big-, and Big- to precisely describe and compare algorithm efficiency.