// Helene Martin, CSE 143 // Hash table implementation of a set, an unordered collection without duplicates. // The hash table stores values at indexes determined by a hashing function. // O(1) average time to add, remove, search. (YAY!!) public class HashSet implements Set { private HashNode[] entries; private int size; // Builds a new HashSet. public HashSet(int capacity) { // set up array with load factor of 0.75 (give the client a little extra // space) entries = new HashNode[(int) (capacity / 0.75)]; } // Add the specified value. public void add(E value) { if (!contains(value)) { int i = indexOf(value); entries[i] = new HashNode(value, entries[i]); size++; } } // True if the value is in the set, false otherwise. public boolean contains(E value) { int i = indexOf(value); HashNode current = entries[i]; while (current != null) { if (current.data.equals(value)) return true; current = current.next; } return false; } // Remove the given value. public void remove(E value) { if (contains(value)) { int i = indexOf(value); if (entries[i].data.equals(value)) entries[i] = entries[i].next; else { HashNode current = entries[i]; while (!current.next.data.equals(value)) current = current.next; current.next = current.next.next; } size--; } } // Returns the size. public int size() { return size; } // True if the set is empty, false otherwise. public boolean isEmpty() { return size == 0; } // Uses the hashing function to find the index of a value. private int indexOf(E value) { return Math.abs(value.hashCode() % entries.length); } // A node representing a single value in a hash table. private static class HashNode { public Object data; public HashNode next; public HashNode(Object data, HashNode next) { this.data = data; this.next = next; } } }