Data Structures, Algorithms, & Applications in Java
Chapter 11, Exercise 33

The code, which is given below, is very similar to that for the class HashChains.


public class HashChainsWithTails
{
   // data members
   private int divisor;               // hash function divisor
   private SortedChainWithTail [] table;      // hash table array
   private int size;                  // number of elements in table

   // constructor
   public HashChainsWithTails(int theDivisor)
   {
      divisor = theDivisor;
   
      // allocate hash table array
      table = new SortedChainWithTail [divisor];

      // allocate the chains
      for (int i = 0; i < divisor; i++)
         table[i] = new SortedChainWithTail();
   }
   
   // instance methods
   /** @return true iff the hash table is empty */
   public boolean isEmpty()
      {return size == 0;}

   /** @return current number of elements in the hash table */
   public int size()
      {return size;}

   /** @return element with specified key
     * @return null if no matching element */
   public Object get(Object theKey)
      {return table[theKey.hashCode() % divisor].get(theKey);}
   
   /** insert an element with the specified key
     * overwrite old element if there is already an
     * element with the given key
     * @return old element (if any) with key = theKey */
   public Object put(Object theKey, Object theElement)
   {
      int b = theKey.hashCode() % divisor;  // home bucket

      // insert
      Object elementToReturn = table[b].put(theKey, theElement);
      if (elementToReturn == null)
         // wasn't a duplicate
         size++;
      return elementToReturn;
   }

   /** @return matching element and remove it
     * @return null if no matching element */
   public Object remove(Object theKey)
   {
      Object elementToReturn =
             table[theKey.hashCode() % divisor].remove(theKey);
      if (elementToReturn != null)
         size--;
      return elementToReturn;
   }
   
   /** output the hash table */
   public void output()
   {
      for (int i = 0; i < divisor; i++)
         System.out.println(table[i]);
      System.out.println("Table size is " + size);
   }
}



We expect the run-time performance of HashChainsWithTails to be superior to that of HashChains because the use of tail nodes reduces the complexity of the loop conditionals used in the methods of HashChainsWithTails relative to the complexity of the loop conditionals used in HashChains.