Deleting an
entry from a
hash table using
Open Addressing
Naive version of the
remove( ) algorithm
of a hash table using
linear probing
- The
initial version
of the remove(k) algorithm
using linear probing:
public V remove(K k) // Return the value associated with key k
{
int hashIdx = hashValue(k);
int i = hashIdx;
do
{
if ( bucket[i] == null ) // Is bucket empty ?
{
return null; // Key k is not in hash table
}
else if (bucket[i].key == k ) // Does bucket contains key k ?
{
V retVal = bucket[i].value;
bucket[i] = AVAILABLE; // Mark bucket as "available"
return retVal; // Return value
}
i = (i + 1)%capacity; // Check in next hash table bucket
} while ( i != hashIdx ); // All entries searched !
return null; // No found
}
|
|
Naive version of the
remove( ) algorithm
of a hash table using
linear probing
- Start the
search
for key y
at the
hash bucket:
public V remove(K k) // Return the value associated with key k
{
int hashIdx = hashValue(k);
int i = hashIdx;
do
{
if ( bucket[i] == null ) // Is bucket empty ?
{
return null; // Key k is not in hash table
}
else if (bucket[i].key == k ) // Does bucket contains key k ?
{
V retVal = bucket[i].value;
bucket[i] = AVAILABLE; // Mark bucket as "available"
return retVal; // Return value
}
i = (i + 1)%capacity; // Check in next hash table bucket
} while ( i != hashIdx ); // All entries searched !
return null; // No found
}
|
|
Naive version of the
remove( ) algorithm
of a hash table using
linear probing
Naive version of the
remove( ) algorithm
of a hash table using
linear probing
Naive version of the
remove( ) algorithm
of a hash table using
linear probing
- If we
find the
entry containing
key k,
we replace it with
null:
public V remove(K k) // Return the value associated with key k
{
int hashIdx = hashValue(k);
int i = hashIdx;
do
{
if ( bucket[i] == null ) // Is bucket empty ?
{
return null; // Key k is not in hash table
}
else if (bucket[i].key == k ) // Does bucket contains key k ?
{
V retVal = bucket[i].value;
bucket[i] = null; // Delete the entry
return retVal; // Return value
}
i = (i + 1)%capacity; // Check in next hash table bucket
} while ( i != hashIdx ); // All entries searched !
return null; // No found
}
|
|
Naive version of the
remove( ) algorithm
of a hash table using
linear probing
Deleting an
entry from a
hash table using
Open Addressing
- Consider the
insert example
where we have
inserted the
keys R, S, V, P:
Hash value
insert(R) 4
insert(S) 6
insert(V) 5
insert(P) 4
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | S | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^ ^
| |
H(P)=4 (P, ..) inserted here
|
- Consider the
entry (P, ..)
(where I omitted the
data for
brevity):
- The hash value
H(P) =
4
- However, because
the bucket 4 was
used,
the
entry (P, ..)
was inserted in
bucket
7
|
|
Deleting an
entry from a
hash table using
Open Addressing
- Suppose we
remove
the entry (S, ..) by
replacing
the entry with
null:
Hash value
insert(R) 4
insert(S) 6
insert(V) 5
insert(P) 4
remove(S):
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^ ^
| |
H(P)=4 (P, ..) inserted here
|
- $64,000 question:
- Will the
get( )
algorithm
still
work for
get(P) ??
|
|
Review:
the get algorithm in
Open Addressing with
linear probing
Problem with
the get algorithm in
Open Addressing with
linear probing
- The get(k) algorithm
starts the
search for
key k at the
hasg bucket:
public V get(K k)
{
int hashIdx = H(k); // Find the hash index for key k
int i = hashIdx; // Start search at hash bucket
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
}
|
|
Problem with
the get algorithm in
Open Addressing with
linear probing
- When get(k)
finds an
empty bucket,
it determines that
key k is
not found:
public V get(K k)
{
int hashIdx = H(k); // Find the hash index for key k
int i = hashIdx; // Start search at hash bucket
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
}
|
|
Deleting an
entry from a
hash table using
Open Addressing
-
Problem:
if we
remove
the entry (S, ..)
replacing
the entry with
null:
Hash value
insert(R) 4
insert(S) 6
insert(V) 5
insert(P) 4
remove(S):
0 1 2 3 4 5 6 7 8 9 10 11
+---+---+---+---+---+---+---+---+---+---+---+---+
bucket[] = | | | | | R | V | | P | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
^ ^ ^
| | |
H(P)=4 | (P, ..) inserted here
|
causes get( ) to conclude P is not found
|
- The get( ) algorithm
no longer
work correctly !!!
|
The AVAILABLE
entry
- To solve the
deletion problem,
a hash table using
Open Addressing uses
a
special entry
called
AVAILABLE:
public Entry<K,V> AVAILABLE = new Entry<>(null, null);
|
- How the
AVAILABLE
entry is
used:
- When an existing
entry in the
hash table is
removed:
- The entry
is replaced by the
AVAILABLE
entry
|
- When you are
searching
for
key k then:
-
AVAILABLE
must be treated as
an empty bucket
(i.e.: it does not contain
any key
- The rehash algorithm
must
continue with the
next search location
|
|
|
❮
❯