DSA - Hashing
Hashing
Section titled “Hashing”Hashing is a technique to map a key to an index of a hash table using a hash functions enabling average time for search, insert, and delete operations.
Hash Table: A hash table is a data structure that stores key–value pairs and uses a hash function to map each key to an index in an arrays allowing O(1) average-time search, insertion, and deletion.
Terminology
- Key (k): Input value to be stored/searched
- Hash Function h(k): Maps key k to table index
- Hash Table: Array of size m (table size)
- Slot/Bucket: Each index position in hash table
- Load Factor (): where n = number of keys, m = table size
- Collision: When two different keys map to same index
- Clustering: Keys accumulate in consecutive slots
Properties of a Good Hash Function
- Deterministic: Same key always gives same index
- Uniform Distribution: Keys spread evenly across table
- Fast Computation: Should compute in time
- Minimizes Collisions: Reduces probability of two keys mapping to same slot
- Uses all table positions: No slot should be favored
- Low clustering: Avoids grouping of keys
Hash Functions
1. Division Method:
- Best practice: m should be prime
- Avoid: Powers of 2 (causes poor distribution)
- Why prime? Better distribution, reduces patterns
- Example: k = 85, m = 11 → h(85) = 85 mod 11 = 8
2. Multiplication Method:
- Knuth suggests: (golden ratio - 1)
- Less sensitive to m: m can be power of 2
- Steps:
- Multiply k by A
- Extract fractional part
- Multiply by m
- Take floor
- Example: k = 123, m = 1000, A = 0.618
- Fractional part = 0.014
- h(123) = 14
3. Mid-Square Method:
- Square the key:
- Extract middle r digits
- Use as hash value
- Example: k = 60, , middle 2 digits = 60
4. Folding Method:
- Fold-Shift: Split key into parts, add them
- Fold-Boundary: Reverse alternate parts before adding
- Example: k = 123456789
- Split: 123 | 456 | 789
- Add: 123 + 456 + 789 = 1368
5. Universal Hashing (Advanced):
- a, b are random coefficients
- p is prime > universe of keys
- Provides theoretical guarantees
Collision
Section titled “Collision”A collision occurs in hashing when two or more different keys are mapped to the same hash table index by a hash function.
- When but
- Unavoidable when: (Pigeonhole Principle)
- Types:
- Primary Clustering: Long runs of occupied slots (in Linear Probing)
- Secondary Clustering: Keys follow same probe sequence (in Quadratic Probing)
Collision Resolution Techniques ⭐
- A. Separate Chaining (Closed Addressing) -> Collision elements are linked together.
- Bucket hashing → one index stores multiple entries in an array/block.
- Chaining → one index points to a linked list.
- B. Open Addressing (Closed Hashing) -> Probe for next empty slot.
- Linear Probing → Search sequentially for next empty slot.
- Quadratic Probing → Search using quadratic gaps to reduce clustering.
- Double Hashing → Use a second hash function to decide probe step size.
| Feature | Close Addressing | Open Addressing |
|---|---|---|
| Another Name | Separate Chaining | Closed Hashing |
| Collision Handling | Store multiple elements at same index using linked list/buckets | Find another empty slot |
| Storage | Outside table possible | Inside table only |
| Extra Memory | Required | Not required |
| Deletion | Easy | Difficult |
| Clustering | Less | More |
| Load Factor | Can be (>1) | Must be (<1) |
The naming is confusing because different books use opposite terminology.
| Term | Method | Meaning |
|---|---|---|
| Open Addressing | probing | All elements stored inside same hash table |
| Closed Addressing / Separate Chaining | chaining | Elements may be stored outside table using linked lists |
Reason: ⭐
- In open addressing, searching stays “open” within table slots.
- In closed addressing, each index is “closed” to a chain/bucket attached to it.
A. Separate Chaining (Closed Addressing)
Section titled “A. Separate Chaining (Closed Addressing)”Method:
- Each table slot contains pointer to linked list
- All keys hashing to same index stored in that list
Operations:
- Insert:
1. Compute h(k)2. Insert k at head of list at table[h(k)]3. Time: O(1)- Search:
1. Compute h(k)2. Traverse list at table[h(k)]3. Time: O(1 + α) average- Delete:
1. Compute h(k)2. Search in list at table[h(k)]3. Delete node4. Time: O(1 + α) averageTime Complexity:
- Best Case: when all keys in different slots
- Average Case: where
- Worst Case: when all keys hash to same slot (single long chain)
Space Complexity:
Expected chain length:
Advantages:
- Simple implementation
- Table never fills ( can be > 1)
- Deletion is easy
- Less sensitive to hash function quality
Disadvantages:
- Extra memory for pointers
- Cache unfriendly (poor locality)
- Memory overhead per node
GATE Formula:
- Average search time = (successful search)
- Average search time = (unsuccessful search)
B. Open Addressing (Closed Hashing)
Section titled “B. Open Addressing (Closed Hashing)”Method:
- All keys stored in table itself
- No external storage
- One key per slot
- Critical: (must have empty slots)
Probe Sequence: where i = 0, 1, 2, …, m-1
General Algorithm:
Insert(k): i = 0 repeat: j = h(k, i) if table[j] is empty or deleted: table[j] = k return j i = i + 1 until i == m1. Linear Probing:
- Probe sequence:
- Example: ,
- Sequence: 5, 6, 7, 8, 9, 0, 1, 2, 3, 4
- Primary Clustering:
- Long runs of occupied consecutive slots form
- Increases average search time
- New keys tend to cluster around existing clusters
- Number of probes (average):
- Successful search:
- Unsuccessful search:
- Advantages:
- Best cache performance
- No extra memory
- Disadvantages:
- Severe primary clustering
- Performance degrades rapidly as
2. Quadratic Probing:
- Common choice: →
- Probe sequence:
- Secondary Clustering:
- Keys with same initial hash follow same probe sequence
- Less severe than primary clustering
- Important Theorem:
- If m is prime and , quadratic probing will find empty slot
- Advantages:
- Eliminates primary clustering
- Better than linear probing
- Disadvantages:
- Secondary clustering
- May not probe all slots
- Requires m to be prime for guarantee
3. Double Hashing:
- Uses two hash functions: and
- Critical requirement: must never be 0
- Best practice: relatively prime to m
- Common choices:
- where
- If m is prime:
- Example:
- m = 13, ,
- k = 14: ,
- Sequence: 1, 5, 9, 0, 4, 8, 12, 3, 7, 11, 2, 6, 10
- Advantages:
- Best distribution among open addressing
- Eliminates both primary and secondary clustering
- Different keys have different probe sequences
- Number of probes (average):
- Successful search:
- Unsuccessful search:
Comparison Table
| Technique | Primary Cluster | Secondary Cluster | Probes (Success) | Probes (Fail) | Cache Performance |
|---|---|---|---|---|---|
| Chaining | No | No | Poor | ||
| Linear Probing | Yes | No | Best | ||
| Quadratic Probing | No | Yes | Medium | Medium | Good |
| Double Hashing | No | No | Good |
Deletion in Hashing
Chaining:
- Simply delete node from linked list
- No special handling needed
- Time:
Open Addressing:
- Problem: Cannot simply mark slot as empty
- Why? Breaks probe sequence for future searches
- Solution: Lazy Deletion (mark as DELETED)
States of a slot:
- EMPTY: Never used
- OCCUPIED: Contains key
- DELETED: Had key, now removed
Search algorithm:
- Continue probing through DELETED slots
- Stop only at EMPTY slot
Insert algorithm:
- Can reuse DELETED slots
- Stop at first DELETED or EMPTY slot
GATE Important: Search stops at EMPTY, not DELETED
Load Factor Effects
Definition: \alpha = \frac{n}{m} = \frac{\text{number of keys\}}{\text{table size\}}
Chaining:
- can be > 1
- Average chain length =
- Performance degrades linearly with
Open Addressing:
- Must maintain
- Performance degrades exponentially as
- Recommended: for good performance
Critical values:
- : Reasonable performance
- : Typical rehashing threshold
- : Severe performance degradation
- : Table full (open addressing fails)
Rehashing
When to rehash:
- When exceeds threshold (typically 0.7)
- Table becomes too full
- Too many collisions
Process:
- Create new table of size (choose prime)
- Recompute hash for all keys
- Insert all keys into new table
- Delete old table
Time Complexity:
- to rehash all n keys
- Amortized cost: per insertion
GATE Note: Rehashing changes all hash values (new table size)
Time Complexity Summary
Average Case (with good hash function):
| Operation | Chaining | Open Addressing |
|---|---|---|
| Insert | ||
| Search (success) | Varies by method | |
| Search (fail) | ||
| Delete |
Worst Case:
- Chaining: - all keys in one chain
- Open Addressing: - must probe entire table
Space Complexity:
- Chaining: - table + linked lists
- Open Addressing: - table only
Applications
- Symbol Tables: Compiler design, variable storage
- Databases: Index structures, quick lookups
- Caching: Web browsers, DNS cache
- Sets/Maps: Dictionary implementations
- Password Storage: Hash + salt
- Checksums: Data integrity verification
- Cryptography: Digital signatures, blockchain
- Routers: IP address lookup
- Spell Checkers: Word lookup
- Duplicate Detection: File systems
GATE Focus Points
- Hash function identification: Division, multiplication, mid-square
- Collision resolution: Identify chaining vs open addressing
- Probe sequence calculation: Linear, quadratic, double hashing
- Number of comparisons: Given and technique
- Clustering detection: Primary vs secondary
- Lazy deletion: When to stop search in open addressing
- Load factor calculations: Effect on performance
- Rehashing: When triggered, new table size
- Prime table sizes: Why important for division method
- Double hashing requirements: , relatively prime to m
Common GATE Traps
- Linear Probing Stop Condition:
- Stop at EMPTY slot, NOT at DELETED slot
- DELETED slots must be probed through
- Open Addressing Load Factor:
- Must maintain
- Table can become full
- Prime Table Size:
- Division method works best with prime m
- Avoids patterns and improves distribution
- Double Hashing Independence:
- must be independent of
- must never return 0
- Quadratic Probing Guarantee:
- Only guaranteed to find slot if m is prime and
- Chaining vs Open Addressing:
- Chaining allows
- Open addressing requires
- Deletion in Open Addressing:
- Cannot simply empty the slot
- Must use lazy deletion (DELETED marker)
- Rehashing Effect:
- All hash values change (new m)
- Not just copying keys to new table
Key Formulae (Must Remember)
Load Factor:
Division Method:
Multiplication Method:
Linear Probing:
Quadratic Probing:
Double Hashing:
Average Probes (Linear Probing - Success):
Average Probes (Linear Probing - Failure):
Average Search Time (Chaining - Success):
Average Search Time (Chaining - Failure):
Performance Comparison Chart
For :
| Method | Successful Search | Unsuccessful Search |
|---|---|---|
| Chaining | 1.25 probes | 0.5 probes |
| Linear Probing | 1.5 probes | 2.5 probes |
| Quadratic Probing | ~1.4 probes | ~2.2 probes |
| Double Hashing | 1.39 probes | 2 probes |
For :
| Method | Successful Search | Unsuccessful Search |
|---|---|---|
| Chaining | 1.45 probes | 0.9 probes |
| Linear Probing | 5.5 probes | 50.5 probes |
| Quadratic Probing | ~3 probes | ~10 probes |
| Double Hashing | 2.56 probes | 10 probes |
Final Insights
- Hashing provides average time, NOT worst case
- Choice of hash function critically affects performance
- Load factor is the single most important performance metric
- Open addressing degrades faster than chaining as increases
- Double hashing is theoretically best for open addressing
- Linear probing is practically fastest due to cache locality
- Prime table sizes matter for division method and quadratic probing
- Lazy deletion is essential for open addressing
- Rehashing is expensive but necessary for maintaining performance
- Universal hashing provides theoretical worst-case guarantees