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

  • Suppose 2 different keys (John and Peter) hash into the same hash bucket (e.g.: 4)

  • The first key (e.g.: John) is inserted in the hash bucket (4):

    Now the hash bucket 4 is full

    (Because each hash bucket can store at most one hash table entry)

Collision resolution in Open Addressing

  • Insertion of the second key (e.g.: Peter) will find that the hash bucket (4) is full:

    The insert algorithm will start at the hash index and find the next available hash bucket that can use used to store the key

  • The procedure to find the next available hash bucket is called:

    • Rehashing
      Note:   rehashing is not random but deterministic (= computable)

Collision resolution in Open Addressing

  • Rehash algorithms used to resolve collision in Open Addressing:

    1. 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, ..
      

    2. Quadratic Probing: uses the "rehash" function:

       rehash(key) = (h+i2)%M   where  h = H(key) and i = 1, 2, ..
      

    3. 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 initial version of the insert algorithm using Linear Probing:

       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");
       }
    

    Note:   we need to modify put( ) slightly later (next webpage)

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

  • Search all the buckets i, i+1, i+2, ...:

       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");
       }
    

    Note: when i == hashIdx again, the search index i has wrap back to the start !

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 initial version of the "get" algorithm using Linear Probing:

       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
       }
    

    Note:   we need to modify get( ) slightly later

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

  • Search all the buckets i, i+1, i+2, ...:

       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 ) // All entries searched
    
           return null;  // Not found
       }
    

    Note: when i == hashIdx again, the search index i has wrap back to the start !

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