// Allison Obourn // CSE 143, Autumn 2015 // This class implements a set using a "hash table" array. // The hash table stores each integer at a particular given index based // on a "hashing function". // This provides O(1) average time to add, remove, and search. (Wow!) import java.util.*; public class HashIntSet { // "load factor" - percentage of array that must be full before resize private static final double LOAD_FACTOR = 0.75; private static final int CAPACITY = 137; // "hash table" - an array of hash "buckets" where values can be stored private List[] elements; private int count; // Creates a new empty set with a hash table of default capacity public HashIntSet() { elements = (List[])(new List[CAPACITY]); } // Adds the given value to this set. If it is already contained in // this set, no change is made, because sets do not allow duplicates. public void add(int value) { if(!contains(value)) { count++; if((count + 0.0) / elements.length > .75) { rehash(); } int index = hashFunction(value); if(elements[index] == null) { elements[index] = new LinkedList(); } elements[index].add(value); } } // Returns true if the given value is contained in this set, else false. public boolean contains(int value) { int index = hashFunction(value); return elements[index] != null && elements[index].contains(value); } // Removes the given value from this set if it is contained in the set. // If the value is not contained in the set, no change is made. public void remove(int value) { count--; int index = hashFunction(value); if(elements[index] != null) { elements[index].remove(value); } } // Helper method to perform a "hashing function" to map the given value to // its appropriate hash table index. private int hashFunction(int value) { return Math.abs(value) % elements.length; } // Resizes this set's hash table array to be twice as large. // Must re-add all values back into the table because their HF indexes // might have changed after the resizing. private void rehash() { List[] oldElements = elements; elements = (List[])(new List[2 * elements.length]); for(List list : oldElements) { if(list != null) { for(int element : list) { add(element); } } } } }