// CSE 143, Winter 2012 // 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" represented by the 'bucket' method. // 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; // "hash table" - an array of hash "buckets" where values can be stored private List[] elementData; private int size; // Creates a new empty set with a hash table of default capacity of 10. public HashIntSet() { elementData = (List[]) new List[10]; size = 0; } // 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) { int h = HF(value); if (!contains(value)) { if (size >= LOAD_FACTOR * elementData.length) { rehash(); } if (elementData[h] == null) { elementData[h] = new LinkedList(); } elementData[h].add(0, value); size++; } } // Returns true if the given value is contained in this set, else false. public boolean contains(int value) { int h = HF(value); return elementData[h] != null && elementData[h].contains(value); } // Returns true if there are no elements in this set. public boolean isEmpty() { return size() == 0; } // 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) { if (contains(value)) { elementData[HF(value)].remove(value); size--; } } // Returns the number of elements in this set. public int size() { return size; } // Returns a string representation of this set for debugging. public String toString() { return Arrays.toString(elementData); } // Helper method to perform a "hashing function" to map the given value to // its appropriate hash table index. private int HF(int value) { return Math.abs(value) % elementData.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[] oldElementData = elementData; elementData = (List[]) new List[2 * elementData.length]; size = 0; for (int i = 0; i < oldElementData.length; i++) { if (oldElementData[i] != null) { for (int value : oldElementData[i]) { add(value); } } } } }