CSE332 Section 4
Hashing!
Warm-Up
public AVLTree fillUniqueTree(List lst){
AVLTree avl = AVLTree();
for(int i = 0; i < lst.size(); i++){
avl.insert(lst.get(i), lst.get(i));
}
return avl;
}
What is the running time if the all elements in lst are unique?
What is the running time if all elements in lst are the same?
O(nlogn)
O(n)
Announcement
Monday July 20 at 5:00pm, Sieg 134
Hashing!!!
Hash Tables Review
Use a small array to store key-value pairs.
Hash function: converts key into an index of the array
Store key at index given by the hash function
If two keys map to the same place (should be a very rare occurrence), we must do a collision resolution!
Good Hash Function Properties - Review
Each subproblem below describes a symptom of a hash function missing one of these properties. Write which missing property best explains the behavior described. (Recall: consistent, uniform, effective, efficient )
Collision Resolution
Collision Resolution
A collision occurs when two keys map onto the same location in a hash table.
Impossible to eliminate since the number of possible keys exceeds table size.
All elements with keys that map to the same table location are kept in a linked list.
If the slot is occupied, we probe the next slot.
On the ith probe, we check the slot with index (h(key) + f(i)) % TableSize.
Linear Probing: f(i) = i
Quadratic Probing: f(i) = i^2
Double Hashing: f(i) = i ᐧ g(key)
There are multiple ways to resolve conflicts:
Problem 1a
Problem 1a: insertion
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Linear Probing
ith probe: (h(key) + i) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Problem 1a: insert 7
Insert 7, 9, 48, 8, 37, 57 into an empty table.
(h(7) + 0) % 10 = 7
Linear Probing
ith probe: (h(key) + i) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | |
9 | |
Problem 1a: insert 9
Insert 7, 9, 48, 8, 37, 57 into an empty table.
(h(9) + 0) % 10 = 9
Linear Probing
ith probe: (h(key) + i) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | |
9 | |
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | |
9 | 9 |
Problem 1a: insert 48
Insert 7, 9, 48, 8, 37, 57 into an empty table.
(h(48) + 0) % 10 = 8
Linear Probing
ith probe: (h(key) + i) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | |
9 | 9 |
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 1a: insert 8
Insert 7, 9, 48, 8, 37, 57 into an empty table.
(h(8) + 0) % 10 = 8
(h(8) + 1) % 10 = 9
(h(8) + 2) % 10 = 0
Linear Probing
ith probe: (h(key) + i) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
0 | 8 |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 1a: insert 37
(h(37) + 3) % 10 = 0
(h(37) + 2) % 10 = 9
(h(37) + 1) % 10 = 8
(h(37) + 0) % 10 = 7
(h(37) + 4) % 10 = 1
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Linear Probing
ith probe: (h(key) + i) % TableSize
0 | 8 |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
0 | 8 |
1 | 37 |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 1a: insert 57
Insert 7, 9, 48, 8, 37, 57 into an empty table.
(h(57) + 0) % 10 = 7
Linear Probing
ith probe: (h(key) + i) % TableSize
0 | 8 |
1 | 37 |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
0 | 8 |
1 | 37 |
2 | 57 |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
(h(57) + 1) % 10 = 8
(h(57) + 2) % 10 = 9
(h(57) + 3) % 10 = 0
(h(57) + 4) % 10 = 1
(h(57) + 5) % 10 = 2
Problem 1a: deletion
Delete 37, 7, 57 from the table.
Linear Probing
ith probe: (h(key) + i) % TableSize
0 | 8 |
1 | 37 |
2 | 57 |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 1a: delete 37
(h(37) + 0) % 10 = 7
Linear Probing
ith probe: (h(key) + i) % TableSize
Delete 37, 7, 57 from the table.
0 | 8 |
1 | 37 |
2 | 57 |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
0 | 8 |
1 | DELETED |
2 | 57 |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
(h(37) + 1) % 10 = 8
(h(37) + 2) % 10 = 9
(h(37) + 3) % 10 = 0
(h(37) + 4) % 10 = 1
Problem 1a: delete 7
(h(7) + 0) % 10 = 7
Linear Probing
ith probe: (h(key) + i) % TableSize
Delete 37, 7, 57 from the table.
0 | 8 |
1 | DELETED |
2 | 57 |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
0 | 8 |
1 | DELETED |
2 | 57 |
3 | |
4 | |
5 | |
6 | |
7 | DELETED |
8 | 48 |
9 | 9 |
Problem 1a: delete 7
(h(57) + 0) % 10 = 7
Linear Probing
ith probe: (h(key) + i) % TableSize
Delete 37, 7, 57 from the table.
(h(57) + 1) % 10 = 8
(h(57) + 2) % 10 = 9
(h(57) + 3) % 10 = 0
(h(57) + 4) % 10 = 1
(h(57) + 5) % 10 = 2
0 | 8 |
1 | DELETED |
2 | 57 |
3 | |
4 | |
5 | |
6 | |
7 | DELETED |
8 | 48 |
9 | 9 |
0 | 8 |
1 | DELETED |
2 | DELETED |
3 | |
4 | |
5 | |
6 | |
7 | DELETED |
8 | 48 |
9 | 9 |
Experiment on 1a
What happens if we now try to remove a
non-existent element (e.g. 17) from the table?
Experiment: delete 17
(h(17) + 0) % 10 = 7
Linear Probing
ith probe: (h(key) + i) % TableSize
Delete 17 from the table.
(h(17) + 1) % 10 = 8
(h(17) + 2) % 10 = 9
(h(17) + 3) % 10 = 0
(h(17) + 4) % 10 = 1
(h(17) + 5) % 10 = 2
(h(17) + 6) % 10 = 3
We have reached an empty slot, but have not encountered 17. Therefore, it must not exist.
0 | 8 |
1 | DELETED |
2 | DELETED |
3 | |
4 | |
5 | |
6 | |
7 | DELETED |
8 | 48 |
9 | 9 |
0 | 8 |
1 | DELETED |
2 | DELETED |
3 | |
4 | |
5 | |
6 | |
7 | DELETED |
8 | 48 |
9 | 9 |
Problem 1b
Problem 1b: insertion
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Quadratic Probing
ith probe: (h(key) + i2) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Problem 1b: insert 7
Insert 7, 9, 48, 8, 37, 57 into an empty table.
(h(7) + 02) % 10 = 7
Quadratic Probing
ith probe: (h(key) + i2) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | |
9 | |
Problem 1b: insert 9
Insert 7, 9, 48, 8, 37, 57 into an empty table.
(h(9) + 02) % 10 = 9
Quadratic Probing
ith probe: (h(key) + i2) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | |
9 | |
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | |
9 | 9 |
Problem 1b: insert 48
Insert 7, 9, 48, 8, 37, 57 into an empty table.
(h(48) + 02) % 10 = 8
Quadratic Probing
ith probe: (h(key) + i2) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | |
9 | 9 |
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 1b: insert 8
Insert 7, 9, 48, 8, 37, 57 into an empty table.
(h(8) + 02) % 10 = 8
(h(8) + 12) % 10 = 9
(h(8) + 22) % 10 = 2
Quadratic Probing
ith probe: (h(key) + i2) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
0 | |
1 | |
2 | 8 |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 1b: insert 37
(h(37) + 22) % 10 = 1
(h(37) + 12) % 10 = 8
(h(37) + 02) % 10 = 7
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Quadratic Probing
ith probe: (h(key) + i2) % TableSize
0 | |
1 | |
2 | 8 |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
0 | |
1 | 37 |
2 | 8 |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 1b: insert 57
Insert 7, 9, 48, 8, 37, 57 into an empty table.
(h(57) + 02) % 10 = 7
Quadratic Probing
ith probe: (h(key) + i2) % TableSize
0 | |
1 | 37 |
2 | 8 |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
0 | |
1 | 37 |
2 | 8 |
3 | |
4 | |
5 | |
6 | 57 |
7 | 7 |
8 | 48 |
9 | 9 |
(h(57) + 12) % 10 = 8
(h(57) + 22) % 10 = 1
(h(57) + 32) % 10 = 6
Problem 1c
Problem 1c: insertion
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Separate Chaining
Use a linked list for each slot
0 | / |
1 | / |
2 | / |
3 | / |
4 | / |
5 | / |
6 | / |
7 | / |
8 | / |
9 | / |
Problem 1c: insert 7
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Separate Chaining
Use a linked list for each slot
(h(7) + 0) % 10 = 7
0 | / |
1 | / |
2 | / |
3 | / |
4 | / |
5 | / |
6 | / |
7 | / |
8 | / |
9 | / |
7 | / |
0 | / |
1 | / |
2 | / |
3 | / |
4 | / |
5 | / |
6 | / |
7 | |
8 | / |
9 | / |
Problem 1c: insert 9
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Separate Chaining
Use a linked list for each slot
(h(9) + 0) % 10 = 9
0 | / |
1 | / |
2 | / |
3 | / |
4 | / |
5 | / |
6 | / |
7 | |
8 | / |
9 | / |
7 | / |
0 | / |
1 | / |
2 | / |
3 | / |
4 | / |
5 | / |
6 | / |
7 | |
8 | / |
9 | |
9 | / |
Problem 1c: insert 48
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Separate Chaining
Use a linked list for each slot
(h(48) + 0) % 10 = 8
0 | / |
1 | / |
2 | / |
3 | / |
4 | / |
5 | / |
6 | / |
7 | |
8 | / |
9 | |
0 | / |
1 | / |
2 | / |
3 | / |
4 | / |
5 | / |
6 | / |
7 | |
8 | |
9 | |
7 | / |
9 | / |
48 | / |
Problem 1c: insert 8
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Separate Chaining
Use a linked list for each slot
(h(8) + 0) % 10 = 8
0 | / |
1 | / |
2 | / |
3 | / |
4 | / |
5 | / |
6 | / |
7 | |
8 | |
9 | |
7 | / |
9 | / |
48 | / |
48 | |
8 | / |
Problem 1c: insert 37
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Separate Chaining
Use a linked list for each slot
(h(37) + 0) % 10 = 7
48 | |
0 | / |
1 | / |
2 | / |
3 | / |
4 | / |
5 | / |
6 | / |
7 | |
8 | |
9 | |
7 | / |
9 | / |
8 | / |
7 | |
37 | / |
Problem 1c: insert 57
Insert 7, 9, 48, 8, 37, 57 into an empty table.
Separate Chaining
Use a linked list for each slot
(h(57) + 0) % 10 = 7
48 | |
0 | / |
1 | / |
2 | / |
3 | / |
4 | / |
5 | / |
6 | / |
7 | |
8 | |
9 | |
7 | / |
9 | / |
8 | / |
7 | |
37 | / |
37 | |
57 | / |
Problem 2
For each hash function, determine which property it lacks and describe why it doesn’t have that property.
Problem 2a
Missing Property? Effective
Justification: changing only accountNum would result in a different object that hashes to the same value.
Problem 2b
Missing Property: Effective
Justification: swapping routingNum and accountNum would result in a different object that hashes to the same value.
Problem 2c
Missing Property: Consistent
Justification: balance is not relevant for determining equivalence (based on the equals() method), so we may have equal objects that hash to different values.
Problem 3
Problem 3a
Describe double hashing.
Problem 3b
Problem 3b: insertion
Insert 7, 9, 48, 8, 37, 57 into an empty table.
h(k) = k % 10
g(k) = 1 + (k % 9)
Double Hashing
ith probe: (h(key) + i * g(key)) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Problem 3b: insert 7
Insert 7, 9, 48, 8, 37, 57 into an empty table.
h(k) = k % 10
g(k) = 1 + (k % 9)
Double Hashing
ith probe: (h(key) + i * g(key)) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | |
9 | |
Problem 3b: insert 9
Insert 7, 9, 48, 8, 37, 57 into an empty table.
h(k) = k % 10
g(k) = 1 + (k % 9)
Double Hashing
ith probe: (h(key) + i * g(key)) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | |
9 | 9 |
Problem 3b: insert 48
Insert 7, 9, 48, 8, 37, 57 into an empty table.
h(k) = k % 10
g(k) = 1 + (k % 9)
Double Hashing
ith probe: (h(key) + i * g(key)) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 3b: insert 8
Insert 7, 9, 48, 8, 37, 57 into an empty table.
h(k) = k % 10
g(k) = 1 + (k % 9)
Double Hashing
ith probe: (h(key) + i * g(key)) % TableSize
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | 8 |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 3b: insert 37
Insert 7, 9, 48, 8, 37, 57 into an empty table.
h(k) = k % 10
g(k) = 1 + (k % 9)
Double Hashing
ith probe: (h(key) + i * g(key)) % TableSize
0 | |
1 | 37 |
2 | |
3 | |
4 | |
5 | |
6 | 8 |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 3b: insert 57
Insert 7, 9, 48, 8, 37, 57 into an empty table.
h(k) = k % 10
g(k) = 1 + (k % 9)
Double Hashing
ith probe: (h(key) + i * g(key)) % TableSize
0 | |
1 | 37 |
2 | |
3 | |
4 | |
5 | 57 |
6 | 8 |
7 | 7 |
8 | 48 |
9 | 9 |
Problem 3c
List two disadvantages of quadratic probing.
Describe how double hashing fixes one of these disadvantages.
Problem 3d
Compare open addressing with separate chaining.
Attributes | Open Addressing | Separate Chaining |
Collision Handling | Handles collisions by searching for an open slot within the table itself. | Handles collisions by adding elements to a chain at the corresponding index. |
Memory Access | Array is laid out contiguously in memory → better memory locality. | Non-contiguous memory → worse memory locality. |
Runtime | Linear probing suffers from primary clustering, but is guaranteed to find an open slot. Quadratic probing suffers from secondary clustering, and is only guaranteed to find an empty slot when 𝜆 < 0.5. Double hashing does not suffer from clustering, but requires an additional hash function (computationally expensive). | Average runtime: O(1 + 𝜆) Best-case runtime: O(1) Worst-case runtime: O(n) |
Thank You!