Closed Addressing vs.
Open Addressing
-
Closed Addressing:
- In closed addressing,
each key is
always
stored in the
hash bucket where the
key is
hashed to.
- Closed addressing
must use some
data structure (e.g.:
linked list) to
store
multiple entries
in the same bucket
|
|
- Example of
closed addressing:
a
hash table using
separate chaining
|
Closed Addressing vs.
Open Addressing
-
Open Addressing:
- In open addressing,
each hash bucket will
store
at most
one
hash table entry
- In open addressing,
a key
may
be stored in
different
hash bucket than where the
key was
hashed to.
|
|
- Example of
open addressing:
Peter
hashed into
bucket 4 but is
stored in
bucket 5
|
Closed Addressing vs.
Open Addressing
-
Entries used in
Open Addressing:
-
Since in
open addressing,
each hash bucket will
store
at most
one
hash table entry:
- The entries
stored
In Open Addressing
do
not
has a
link variable
|
|
- Entries used in
open addressing:
no linking field
|
The Entry class
for a
hash table using
Open Addressing
- We can
used the
original
Entry<K,V> class
(which was used
in the
ArrayMap<K,V>)
in the
Open Addressing
technique:
public class Entry<K,V>
{
private K key; // Key
private V value; // Value
public Entry(K k, V v) // Constructor
{
key = k;
value = v;
}
... // Methods omitted for brevity
}
|
- We have used this
Entry<sK,V> class
to
implement the
ArrayMap
dictionary
data structure
- The same
Entry object
can be used in
Open Addressing
|
Collision resolution in
Open Addressing
Collision resolution in
Open Addressing
Collision resolution in
Open Addressing
- Rehash algorithms used to
resolve
collision in
Open Addressing:
-
Linear Probing:
- In linear probing,
the hash table is
searched sequentially
starting from the
hash index value
|
In other words, the "rehash" function
is:
rehash(key) = (h+i)%M where h = H(key) and i = 1, 2, ..
|
-
Quadratic Probing: uses
the "rehash" function:
rehash(key) = (h+i2)%M where h = H(key) and i = 1, 2, ..
|
-
Double hashing: which uses
the "rehash" function:
rehash(key) = (h+i*H2(key))%M // H2 is a 2nd hash function
|
|
|
Linear Probing
- We will now study a
hash table using
Open Addressing with
linear probing
as collision resolution method
- For simplicity:
- I will use a hash table with
12 entries
- The keys used in
the example consists of a
single character
|
- The initial
(empty}
hash table:
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
|
- Remember that in
Open Addressing:
- Each bucket can
store at most
one
entry (= (key, value) pair)
|
|
The insert algorithm in
Open Addressing with
linear probing
- Psuedo code of the
insert algorithm using
Linear Probing:
void put(Key k, Value v)
{
int hashValue = H(key); // Hash value
Starting at i = hashValue
Increasing i = i + 1 // = Linear Probing Algorithm
Check every bucket[i]:
{
if ( bucket[i] == empty )
{
bucket[i] = new Entry(k,v); // Insert (k,v)
return;
}
else if ( bucket[i].key == k )
{
bucket[i].value = v; // Update value
return;
}
}
System.out.println("Full");
}
|
|
The insert algorithm in
Open Addressing with
linear probing
The insert algorithm in
Open Addressing with
linear probing
- Start the
search for
key k at
bucket hashIdx:
public void put(K k, V v)
{
int hashIdx = H(k); // Find the hash index for key k
int i = hashIdx;
do
{
if ( entry[i] == null ) // Is entry empty ?
{
bucket[i] = new Entry<>(k,v);
return;
}
else if (entry[i].key == k ) // Does entry contains key k ?
{
bucket[i].value = v;
return;
}
i = (i + 1)%M; // Check in next hash table entry
} while ( i != hashIdx ) // Hash table is full...
System.out.println("Full");
}
|
|
The insert algorithm in
Open Addressing with
linear probing
The insert algorithm in
Open Addressing with
linear probing
- If we
find an
empty entry, then
insert (k,v)
in that empty entry:
public void put(K k, V v)
{
int hashIdx = H(k); // Find the hash index for key k
int i = hashIdx;
do
{
if ( entry[i] == null ) // Is entry empty ?
{
bucket[i] = new Entry<>(k,v);
return;
}
else if (entry[i].key == k ) // Does entry contains key k ?
{
bucket[i].value = v;
return;
}
i = (i + 1)%M; // Check in next hash table entry
} while ( i != hashIdx ) // All entries searched !
System.out.println("Full");
}
|
|
The insert algorithm in
Open Addressing with
linear probing
- If we
find the
key k, then
update the value
with v:
public void put(K k, V v)
{
int hashIdx = H(k); // Find the hash index for key k
int i = hashIdx;
do
{
if ( entry[i] == null ) // Is entry empty ?
{
bucket[i] = new Entry<>(k,v);
return;
}
else if (entry[i].key == k ) // Does entry contains key k ?
{
bucket[i].value = v;
return;
}
i = (i + 1)%M; // Check in next hash table entry
} while ( i != hashIdx ) // All entries searched !
System.out.println("Full");
}
|
|
The insert algorithm in
Open Addressing with
linear probing
- If the
hash table is
full,
we exit
without inserting
(k,v):
public void put(K k, V v)
{
int hashIdx = H(k); // Find the hash index for key k
int i = hashIdx;
do
{
if ( entry[i] == null ) // Is entry empty ?
{
bucket[i] = new Entry<>(k,v);
return;
}
else if (entry[i].key == k ) // Does entry contains key k ?
{
bucket[i].value = v;
return;
}
i = (i + 1)%M; // Check in next hash table entry
} while ( i != hashIdx ) // All entries searched !
System.out.println("Full");
}
|
|
Example insert operation in
Open Addressing with
linear probing
- Initial
hash table
content:
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
Example insert operation in
Open Addressing with
linear probing
- We insert
4 entries:
R, S, V, P
(with the data
omitted for
brevity):
Hash value
put(R) 4
put(S) 6
put(V) 5
put(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
Example insert operation in
Open Addressing with
linear probing
- Put(S):
hash value = 4 and
bucket 4 is
empty
Hash value
put(R) 4
put(S) 6
put(V) 5
put(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
--> insert (R, ...) in bucket 4 (data omitted for brevity)
|
|
Example insert operation in
Open Addressing with
linear probing
- Put(S):
hash value = 6 and
bucket 6 is
empty
Hash value
put(R) 4
put(S) 6
put(V) 5
put(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | | S | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
--> insert (S, ...) in bucket 6 (data omitted for brevity)
|
|
Example insert operation in
Open Addressing with
linear probing
- Put(V):
hash value = 5 and
bucket 6 is
empty
Hash value
put(R) 4
put(S) 6
put(V) 5
put(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
--> insert (V, ...) in bucket 5 (data omitted for brevity)
|
|
Example insert operation in
Open Addressing with
linear probing
- Put(P):
hash value = 4 and
bucket 4 is
full
Hash value
put(R) 4
put(S) 6
put(V) 5
put(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
|
--> insert (P, ...) in bucket 4 --- Cannot - full
|
- We must rehash using
rehash(P) = (4 +
i)%M,
i = 1, 2, 3, .... (i=1)
|
Example insert operation in
Open Addressing with
linear probing
- Put(P):
try the
next
bucket 5:
also
full...
Hash value
put(R) 4
put(S) 6
put(V) 5
put(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
|
--> insert (P, ...) in bucket 5 --- Cannot - full
|
- We must rehash using
rehash(P) = (4 +
i)%M,
i = 1, 2, 3, .... (i=2)
|
Example insert operation in
Open Addressing with
linear probing
- Put(P):
try the
next
bucket 6:
also
full...
Hash value
put(R) 4
put(S) 6
put(V) 5
put(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
|
--> insert (P, ...) in bucket 6 --- Cannot - full
|
- We must rehash using
rehash(P) = (4 +
i)%M,
i = 1, 2, 3, .... (i=3)
|
Example insert operation in
Open Addressing with
linear probing
- Put(P):
try the
next
bucket 7:
empty !!!...
Hash value
put(R) 4
put(S) 6
put(V) 5
put(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
|
--> insert (P, ...) in bucket 7 --- OK - empty
|
- (P, data(P)) is
inserted in
bucket[7] ---
done !
|
Additional
example insert operation in
Open Addressing with
linear probing
- Put(A):
hash value = 11
and bucket 11 is
empty
Hash value
put(A) 11
put(B) 11
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | A |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
|
--> insert (A, ...) in bucket 11 --- OK - empty
|
- (A, data(A)) is
inserted in
bucket[11] ---
done !
|
Additional
example insert operation in
Open Addressing with
linear probing
- Put(B):
hash value = 11 and
bucket 11 is
full
Hash value
put(A) 11
put(B) 11
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | | | | | A |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
|
--> insert (B, ...) in bucket 11 --- Cannot - full
|
- We must rehash using
rehash(B) = (11 +
i)%M,
i = 1, 2, 3, .... (i=1)
|
Additional
example insert operation in
Open Addressing with
linear probing
- Put(B):
try the
nxt
bucket
12%12 = 0
--- it is
empty
Hash value
put(A) 11
put(B) 11
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | B | | | | R | V | S | | | | | A |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
|
--> insert (B, ...) in bucket 0 --- OK - empty
|
-
(B, data(B))
is inserted in
bucket[11]
--- done !
|
The get algorithm in
Open Addressing with
linear probing
- Psuedo code of the
"get" algorithm using
Linear Probing:
V get(Key k)
{
int hashValue = H(key); // Hash value
Starting at i = hashValue
Increasing i = i + 1 // = Linear Probing Algorithm
Check every bucket[i]:
{
if ( bucket[i] == empty )
{
return null; // Not found
}
else if ( bucket[i].key == k ) // FOUND
{
return bucket[i].value; // Return value
}
}
return null; // Not found
}
|
|
The get algorithm in
Open Addressing with
linear probing
The get algorithm in
Open Addressing with
linear probing
- Start the
search for
key k at
bucket hashIdx:
public V get(K k)
{
int hashIdx = H(k); // Find the hash index for key k
int i = hashIdx;
do
{
if ( entry[i] == null ) // Is entry empty ?
{
return null;
}
if (entry[i].key == k ) // FOUND
{
return bucket[i].value;
}
i = (i + 1)%M; // Check in next hash table entry
} while ( i != hashIdx ) // Hash table is full...
return null; // Not found
}
|
|
The get algorithm in
Open Addressing with
linear probing
The get algorithm in
Open Addressing with
linear probing
- If we
find an
empty entry, then
key k is
not stored in the
hash table:
public V get(K k)
{
int hashIdx = H(k); // Find the hash index for key k
int i = hashIdx;
do
{
if ( entry[i] == null ) // Is entry empty ?
{
return null; // NOT found
}
if (entry[i].key == k ) // FOUND
{
return bucket[i].value;
}
i = (i + 1)%M; // Check in next hash table entry
} while ( i != hashIdx ) // All entries searched
return null; // Not found
}
|
|
The get algorithm in
Open Addressing with
linear probing
- If we
find the
key k, then
we return the
corresponding value:
public V get(K k)
{
int hashIdx = H(k); // Find the hash index for key k
int i = hashIdx;
do
{
if ( entry[i] == null ) // Is entry empty ?
{
return null; // NOT found
}
else if (entry[i].key == k ) // FOUND
{
return bucket[i].value;
}
i = (i + 1)%M; // Check in next hash table entry
} while ( i != hashIdx ) // All entries searched
return null; // Not found
}
|
|
The get algorithm in
Open Addressing with
linear probing
- If we look through the
whole hash table and
did not find
key k:
return null
public V get(K k)
{
int hashIdx = H(k); // Find the hash index for key k
int i = hashIdx;
do
{
if ( entry[i] == null ) // Is entry empty ?
{
return null; // NOT found
}
else if (entry[i].key == k ) // FOUND
{
return bucket[i].value;
}
i = (i + 1)%M; // Check in next hash table entry
} while ( i != hashIdx ) // All entries searched
return null; // NOT found
}
|
|
Example get (lookup) operation in
Open Addressing with
linear probing
- Get(R):
hash value = 4 and
the key R is
found in the
bucket:
Hash value
get(R) 4
get(S) 6
get(V) 5
get(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
R|
--> get(R) --> search in bucket 4 --- found
|
- Note:
get(S) and
get(V)
are
processed in the
same manner
|
Example get (lookup) operation in
Open Addressing with
linear probing
- Get(P):
hash value = 4
but
the key P is
not found in the
bucket:
Hash value
get(R) 4
get(S) 6
get(V) 5
get(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
P|
--> get(P) --> search in bucket 4 --- not found
|
- We must rehash using
rehash(P) = (4 +
i)%M,
i = 1, 2, 3, .... (i=1)
|
Example get (lookup) operation in
Open Addressing with
linear probing
- Get(P):
search in
bucket 5
for P --
but
the key P is
not found in the
bucket:
Hash value
get(R) 4
get(S) 6
get(V) 5
get(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
P|
--> get(P) --> search in bucket 5 --- not found
|
- We must rehash using
rehash(P) = (4 +
i)%M,
i = 1, 2, 3, .... (i=2)
|
Example get (lookup) operation in
Open Addressing with
linear probing
- Get(P):
search in
bucket 6
for P --
but
the key P is
not found in the
bucket:
Hash value
get(R) 4
get(S) 6
get(V) 5
get(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
P|
--> get(P) --> search in bucket 6 --- not found
|
- We must rehash using
rehash(P) = (4 +
i)%M,
i = 1, 2, 3, .... (i=3)
|
Example get (lookup) operation in
Open Addressing with
linear probing
- Get(P):
search in
bucket 7
for P --
found !!!
Hash value
get(R) 4
get(S) 6
get(V) 5
get(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
P|
--> get(P) --> search in bucket 7 --- found
|
- Done
|
Example get (lookup) operation
with an non-existing key
-
Get(X)
where
hash value = 4
but
the key X is
not found in the
hash table:
Hash value
get(X) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
X|
--> get(P) --> search in bucket 4
Notice: key X is not found in the hash table
|
- Let's see
how this
search is
different from
the previous search.
|
Example get (lookup) operation
with an non-existing key
- Get(X)
searches in
bucket 4
but
the key X is
not found in the
bucket:
Hash value
get(X) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
X|
--> get(X) --> search in bucket 4 --- not found
|
- We must rehash using
rehash(P) = (4 +
i)%M,
i = 1, 2, 3, .... (i=1)
|
Example get (lookup) operation
with an non-existing key
- Get(X)
searches in
bucket 5 next
but
the key X is
not found in the
bucket:
Hash value
get(X) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
X|
--> get(X) --> search in bucket 5 --- not found
|
- We must rehash using
rehash(P) = (4 +
i)%M,
i = 1, 2, 3, .... (i=2)
|
Example get (lookup) operation
with an non-existing key
- Get(X)
now searches in
bucket 6 next
but
the key X is
not found in the
bucket:
Hash value
get(X) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
X|
--> get(X) --> search in bucket 6 --- not found
|
- We must rehash using
rehash(P) = (4 +
i)%M,
i = 1, 2, 3, .... (i=3)
|
Example get (lookup) operation
with an non-existing key
- Get(X)
then searches in
bucket 7 next
but
the key X is
not found in the
bucket:
Hash value
get(X) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
X|
--> get(X) --> search in bucket 7 --- not found
|
- We must rehash using
rehash(P) = (4 +
i)%M,
i = 1, 2, 3, 4, .... (i=4)
|
Example get (lookup) operation
with an non-existing key
- Get(X)
finally searches in
bucket 8
and
finds an
empty bucket:
Hash value
get(X) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^
X|
--> get(X) --> search in bucket 8 --- find an empty bucket
==> This means X is not found in the hash table !
(If X were stored in the hash table
it must be inside the non-empty series
|
- Done.
|
Demo program --- Linear Probing (without deletion)
- Demo program showing
put( ) and
get( )
without
remove( ):
public static void main(String[] args)
{
Dictionary<String,String> H = new HashTableLinProbe<>(5);
H.put("ice", "cold");
H.put("fire", "hot");
H.put("rock", "hard");
H.put("wool", "soft");
H.put("sun", "hot");
H.put("sun", "**bright**"); // Updates
H.put("moon", "shine"); // *** Full ***
System.out.println("\n**** Test get(): ****");
System.out.println("ice:" + H.get("ice"));
System.out.println("sun:" + H.get("sun"));
System.out.println("abc:" + H.get("abc")); // Not found
}
|
|
DEMO:
15-hashing/20-open-addressing/Demo.java
+ HashTableLinProbe.java
❮
❯