CSE332 Section 5
Hashing
Originally by James Richie Sulaeman,
Revised by Rubee Zhao & Vicky Ye
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
Hashing
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
Problem 2a
Describe double hashing.
Problem 2b
Problem 2b: 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 2b: 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 2b: 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 2b: 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 2b: 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 2b: 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 2b: 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 2c
List two disadvantages of quadratic probing.
Describe how double hashing fixes one of these disadvantages.
Problem 2d
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!