Hashing
Chapter: 3.3 Hashing Difficulty Level: 2 — Recall (definitions, standard problems, short derivations) Time Limit: 30 minutes Total Marks: 40
Instructions
- Answer all questions.
- Show working for numeric questions.
- Use notation where mathematics is required.
Q1. State the three essential properties of a good hash function and give one sentence explaining each. (3 marks)
Q2. Define the load factor of a hash table in terms of the number of stored elements and the number of buckets . If a chaining hash table has elements in buckets, compute . (3 marks)
Q3. Briefly contrast chaining and open addressing as collision resolution strategies. List one advantage of each. (4 marks)
Q4. A hash table of size uses linear probing with hash function . Insert the keys in this order: . Show the final contents of each slot (–). (6 marks)
Q5. Explain why deletion in an open-addressing hash table cannot simply set the slot to empty. Describe the tombstone (deleted marker) technique and how it affects search and insert. (5 marks)
Q6. A hash table using double hashing has , with and . Give the probe sequence (first three slots examined) for inserting key . (4 marks)
Q7. Define amortized in the context of hash table insertion with resizing (doubling). In one or two lines, explain why occasional rehashing still gives amortized cost. (4 marks)
Q8. State the defining property of a universal family of hash functions . What probabilistic guarantee does choosing uniformly at random from provide for two distinct keys ? (4 marks)
Q9. Using a hash-based approach, describe how to solve the two-sum problem (find indices such that ) in a single pass. State the time complexity. (4 marks)
Q10. A Python dict and set are built on hash tables. State (i) what open-addressing scheme underlies CPython's dict, and (ii) one requirement a key must satisfy to be usable in a dict. (3 marks)
END OF PAPER
Answer keyMark scheme & solutions
Q1. (3 marks — 1 each)
- Deterministic: the same key always hashes to the same value (else lookups fail). (1)
- Uniform: distributes keys evenly across buckets to minimise collisions. (1)
- Fast: computable in / constant time so operations stay efficient. (1)
Q2. (3 marks)
- Definition: . (2)
- Computation: . (1)
Q3. (4 marks)
- Chaining: each bucket holds a linked list (or dynamic structure) of colliding entries; the table stores pointers to chains. (1)
- Open addressing: all entries stored directly in the table array; collisions resolved by probing for another slot. (1)
- Advantage of chaining: handles high load factors () gracefully; simple deletion. (1)
- Advantage of open addressing: better cache locality, no pointer/linked-list overhead. (1)
Q4. (6 marks) :
- → slot 1
- → slot 0
- → slot 6
- → occupied, probe 2 → slot 2
- → occupied 1,2 probe 3 → slot 3
- → occupied, probe 4 → slot 4
Final table (1 mark per correct slot placement, 6 total):
| Slot | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| Key | 700 | 50 | 85 | 92 | 73 | — | 76 |
Q5. (5 marks)
- If we simply empty the slot, a later search that probed through that slot to reach a key beyond it would now terminate early (hit an empty slot) and wrongly report "not found". (2)
- Tombstone: mark the slot with a special DELETED marker rather than empty. (1)
- Search: treats a tombstone as "occupied, keep probing" — does not stop. (1)
- Insert: may reuse a tombstone slot (treats it as available). Note: many tombstones degrade performance → periodic rehashing clears them. (1)
Q6. (4 marks)
- . (1)
- . (1)
- Probe sequence: :
- :
- :
- : (2 for correct first three: 3, 9, 4)
Q7. (4 marks)
- Amortized : the average cost per operation over a sequence of operations is constant, even if individual operations are occasionally expensive. (2)
- With doubling, resizing elements costs but happens after cheap inserts; the total cost of inserts is (geometric series ), so cost per insert amortized. (2)
Q8. (4 marks)
- Universal family: is universal if for any two distinct keys , where is the table size and is chosen uniformly at random from . (3)
- Guarantee: the probability that two distinct keys collide is at most , independent of the input, giving expected operations regardless of adversarial keys. (1)
Q9. (4 marks)
- Maintain a hash map from value → index. Iterate through the array; for each , check whether is already in the map. (2)
- If found, return the stored index and ; otherwise insert and continue. (1)
- Time complexity: (each lookup/insert is expected ). (1)
Q10. (3 marks)
- (i) CPython's dict uses open addressing (a perturbation-based probe sequence), not chaining. (2)
- (ii) A key must be hashable — implement
__hash__and be immutable/equality-consistent (equal keys must have equal hashes). (1)
[
{"claim":"Load factor n=30, m=8 gives 3.75","code":"result = (Rational(30,8) == Rational(15,4)) and (float(Rational(30,8))==3.75)"},
{"claim":"Linear probing final positions for keys 50,700,76,85,92,73 in m=7","code":"m=7\ntable=[None]*m\nfor k in [50,700,76,85,92,73]:\n i=k%m\n while table[i] is not None:\n i=(i+1)%m\n table[i]=k\nresult = table==[700,50,85,92,73,None,76]"},
{"claim":"Double hashing probe sequence for k=25, m=11 is 3,9,4","code":"m=11\nk=25\nh1=k%m\nh2=1+(k%10)\nseq=[(h1+i*h2)%m for i in range(3)]\nresult = seq==[3,9,4]"},
{"claim":"Geometric doubling sum 1+2+...+n is O(n): total < 2n","code":"n=1024\ntotal=0\ns=1\nwhile s<=n:\n total+=s\n s*=2\nresult = total < 2*n*2 and total==2047"}
]