// CSE 373, Winter 2013, Marty Stepp // A HashIntSet object represents a set of objects using a hash table // as the internal data structure. // The hash table uses linear probing to resolve collisions. import java.util.Arrays; public class HashSet implements Set { private static final Object REMOVED = new Object(); private Object[] elements; private int size; // Constructs a new empty set of integers. public HashSet() { elements = new Object[10]; size = 0; } // Adds the given value to this set, // if it was not already contained in the set. public void add(E value) { if ((double) size / elements.length >= 0.75) { rehash(); } int h = hash(value); while (elements[h] != null && !elements[h].equals(value) && !elements[h].equals(REMOVED)) { // collision; "linear probing" to find a spot h = (h + 1) % elements.length; } // elements[h] == 0 || elements[h] == value if (elements[h] != value) { elements[h] = value; size++; } } // Returns whether the given value is found in this set. public boolean contains(E value) { int h = hash(value); while (elements[h] != null) { if (elements[h].equals(value)) { return true; } // collision; "linear probing" to find a spot h = (h + 1) % elements.length; } // found a 0; not here return false; } // Returns true if there are no elements in this set. public boolean isEmpty() { return size == 0; } // Removes the given element value from this set, // if it was found in the set. public void remove(E value) { int h = hash(value); while (elements[h] != null && !elements[h].equals(value)) { // collision; "linear probing" to find a spot h = (h + 1) % elements.length; } // elements[h] == 0 || elements[h] == value if (elements[h] == value) { elements[h] = REMOVED; size--; } } // Returns the number of elements in this set. public int size() { return size; } // Returns a text representation of this set. // TODO: finish (this is not a proper toString; it shows the internal array) public String toString() { return Arrays.toString(elements); } // Debugging helper that prints the inner hash table. public void debug() { System.out.printf("%7s", "index"); for (int i = 0; i < elements.length; i++) { System.out.printf("%7d", i); } System.out.println(); System.out.printf("%7s", "value"); for (int i = 0; i < elements.length; i++) { System.out.printf("%7d", elements[i]); } System.out.println(); System.out.printf("%7s%7d\n\n", "size", size); } // resize to 2x as big @SuppressWarnings("unchecked") private void rehash() { Object[] big = new Object[2 * elements.length]; Object[] old = elements; size = 0; elements = big; for (Object o : old) { if (o != null && o != REMOVED) { add((E) o); } } } // hash function for mapping values to indexes private int hash(E value) { return Math.abs(value.hashCode()) % elements.length; } }