/* * Kyle Smith * 04/06/09 * Computer Science II * 22C:021 * Homework 6 * */ import java.util.LinkedList; import java.util.List; import java.util.*; // SeparateChaining Hash table class // // CONSTRUCTION: an approximate initial size or default of 101 // // ******************PUBLIC OPERATIONS********************* // void insert( x ) --> Insert x // void remove( x ) --> Remove x // boolean contains( x ) --> Return true if x is present // void makeEmpty( ) --> Remove all items /** * Separate chaining table implementation of hash tables. * Note that all "matching" is based on the equals method. * @author Mark Allen Weiss * EDITED BY KYLE ALAN SMITH ON April 6, 2009 */ public class SeparateChainingHashTable { /** * Construct the hash table. */ public SeparateChainingHashTable( ) { this( DEFAULT_TABLE_SIZE ); } /** * Construct the hash table. * @param size approximate table size. */ public SeparateChainingHashTable( int size ) { theLists = new LinkedList[ nextPrime( size ) ]; for( int i = 0; i < theLists.length; i++ ) theLists[ i ] = new LinkedList( ); } /** * Insert into the hash table. If the item is * already present, then do nothing. * @param x the item to insert. */ public void insert( AnyType x ) { List whichList = theLists[ myhash( x ) ]; if( !whichList.contains( x ) ) { whichList.add( x ); // Rehash; see Section 5.5 if( ++currentSize > theLists.length ) rehash( ); } } /** * Remove from the hash table. * @param x the item to remove. */ public void remove( AnyType x ) { List whichList = theLists[ myhash( x ) ]; if( whichList.contains( x ) ) { whichList.remove( x ); currentSize--; } } /** * Find an item in the hash table. * @param x the item to search for. * @return true if x is not found. */ public boolean contains( AnyType x ) { List whichList = theLists[ myhash( x ) ]; return whichList.contains( x ); } /** * Make the hash table logically empty. */ public void makeEmpty( ) { for( int i = 0; i < theLists.length; i++ ){ theLists[ i ].clear( ); } currentSize = 0; } /** * A hash routine for String objects. * @param key the String to hash. * @param tableSize the size of the hash table. * @return the hash value. */ public static int hash( String key, int tableSize ) { int hashVal = 0; for( int i = 0; i < key.length( ); i++ ) hashVal = 37 * hashVal + key.charAt( i ); hashVal %= tableSize; if( hashVal < 0 ) hashVal += tableSize; return hashVal; } private void rehash( ) { List [ ] oldLists = theLists; // Create new double-sized, empty table theLists = new List[ nextPrime( 2 * theLists.length ) ]; for( int j = 0; j < theLists.length; j++ ) theLists[ j ] = new LinkedList( ); // Copy table over currentSize = 0; for( int i = 0; i < oldLists.length; i++ ) for( AnyType item : oldLists[ i ] ) insert( item ); } private int myhash( AnyType x ) { int hashVal = x.hashCode( ); hashVal %= theLists.length; if( hashVal < 0 ) hashVal += theLists.length; return hashVal; } private static final int DEFAULT_TABLE_SIZE = 101; /** The array of Lists. */ private List [ ] theLists; private int currentSize; /** * Internal method to find a prime number at least as large as n. * @param n the starting number (must be positive). * @return a prime number larger than or equal to n. */ private static int nextPrime( int n ) { if( n % 2 == 0 ) n++; for( ; !isPrime( n ); n += 2 ) ; return n; } /** * Internal method to test if a number is prime. * Not an efficient algorithm. * @param n the number to test. * @return the result of the test. */ private static boolean isPrime( int n ) { if( n == 2 || n == 3 ) return true; if( n == 1 || n % 2 == 0 ) return false; for( int i = 3; i * i <= n; i += 2 ) if( n % i == 0 ) return false; return true; } // code for implementation of BinaryHeap delete method - finds a given element in the // hash table and returns that element's location value (an integer) public int getHeapLocation(AnyType x){ if(this.contains(x)){ // only procedes if the element exists List whichList = theLists[myhash(x)]; // finds linkedlist that contains the element x if(x instanceof Foo){ // checks to ensure the stored element is a Foo if(whichList.contains(x)){ // makes sure the element x is in this linkedlist ListIterator itr = whichList.listIterator(); // iterator for going through this linked list while(itr.hasNext()){ // only procedes until the last element of the list Foo temp = (Foo)itr.next(); // the next item in the list if(x.equals(temp)){ return temp.location; // returns location of the heap element } } } } } return 0; // x not in 'this' hash table } }