| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- /**
- * Hashtable implementation
- * Contains Iterator
- *
- * Project 2
- *
- * @author Thomas Flucke tflucke
- * @author Lara Luu ljluu
- *
- * @since 2015/11/11
- *
- * @see Comparable
- */
- import java.util.Iterator;
- import java.util.NoSuchElementException;
- public class HashTable
- {
- /**
- * A private class used by Hashtable
- * Creates HashEntries to be used in the hashtable consisting of an element (type Object) and a boolean active
- *
- * Project 4
- *
- * @author Thomas Flucke tflucke
- * @author Lara Luu ljluu
- *
- * @since 2015/10/21
- */
- private class HashEntry
- {
- public Object elm; // element stored in the hashEntry
- public boolean active; // boolean stating whether or not the entry can be used (used for "deleting" an entry)
-
- /**
- * Constructor creating a new hash entry of Object type
- */
- public HashEntry(Object elm)
- {
- this.elm = elm;
- active = true;
- }
- }
-
- private HashEntry[] table; // Creates the table array in which the hash entries will be held
- private int size; // parameter for the number of elements inside the hashtable
-
- /**
- * Constructor creating a new hash table
- * Length of the array: next prime number after doubling the capacity
- */
- public HashTable(int tableCapacity)
- {
- table = new HashEntry[nextPrime(2*tableCapacity)];
- size = 0;
- }
-
- /**
- * Method returning whether or not the parameter (num) is prime
- * @param num
- * @return true if the input is prime, false otherwise
- */
- private static boolean isPrime(int num)
- {
- if (num % 2 == 0)
- {
- return false;
- }
- for (int i = 3; i*i <= num; i += 2)
- {
- if (num % i == 0)
- {
- return false;
- }
- }
- return true;
- }
- /**
- * Method for finding the next prime number specified in the parameter (num)
- * @param num
- * @return the next prime integer
- */
- private static int nextPrime(int num)
- {
- if (num % 2 == 0)
- {
- num++;
- }
- while (!isPrime(num))
- {
- num += 2;
- }
- return num;
- }
-
- /**
- * Method returning whether or not a hashEntry is active
- * @param entry
- * @return true if the hashEntry is active, false if it is not
- */
- private static boolean isActive(HashEntry entry)
- {
- return entry != null && entry.active;
- }
-
- /**
- * A private class used by Hashtable
- * Visits each number in the order of its hash
- *
- * Project 4
- *
- * @author Thomas Flucke tflucke
- * @author Lara Luu ljluu
- *
- * @since 2015/10/21
- */
- private class Iter implements Iterator<Object>
- {
- private int cursor; // cursor: points to current location on the hashTable
-
- /**
- * Constructor creating an iterator
- * cursor starts at -1
- */
- public Iter()
- {
- cursor = -1;
- findNextElm();
- }
- /**
- * function moving the cursor onto the next element
- */
- private void findNextElm()
- {
- cursor++;
- while (cursor < table.length && !isActive(table[cursor]))
- {
- cursor++;
- }
- }
-
- /**
- * Returning a boolean stating whether or not there is a next node
- */
- @Override
- public boolean hasNext() {
- return cursor < table.length;
- }
- /**
- * Returns the next element in the in-level traversal
- */
- @Override
- public Object next() {
- if (!hasNext())
- {
- throw new NoSuchElementException();
- }
- Object tmp = table[cursor].elm; //temp variable holding the value of the cursor
- findNextElm();
- return tmp;
- }
- /**
- * throws an UnsupportedOperationException; is not meant to be used in the class
- */
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Method inserting an element of type Object in the hashTable
- * resizes the hashtable if it the size of the hashTable is greater than half of the hashTable
- * @param item
- */
- public void insert(Object item)
- {
- int index = findNextIndex(item);
- if (table[index] == null)
- {
- table[index] = new HashEntry(item);
- size++;
- }
- else
- {
- table[index].active = true;
- }
- if (size >= table.length / 2)
- {
- rehash();
- }
- }
-
- /**
- * Returns the unique identifier for the object
- * @param obj
- * @return the index of the array where the element will be stored (hash)
- */
- private int hash(Object obj)
- {
- return Math.abs(obj.hashCode()) % table.length;
- }
-
- /**
- * finds the next available index for the object to be stored if the first spot is already taken
- * @param obj
- * @return the next index where the object will be stored
- */
- private int findNextIndex(Object obj)
- {
- int hash = hash(obj);
- int i = 0;
- int index = hash;
- while (table[index] != null && !table[index].elm.equals(obj))
- {
- i++;
- index = (hash + i*i) % table.length;
- }
- return index;
- }
-
- /**
- * Creates a new hashtable twice the size of the old hashTable
- * Moves all the old elements into the new hashTable
- */
- private void rehash()
- {
- HashEntry[] tmp = table; //creates temporary table twice the size of the old one
- table = new HashEntry[nextPrime(table.length*2)];
- for (HashEntry he : tmp)
- {
- if (isActive(he))
- {
- insert(he.elm);
- }
- }
- }
-
- /**
- * Method "deleting" the specified element in the hashTable
- * To "delete": makes the element inactive by changing the active instance variable to "false"
- * @param item
- */
- public void delete(Object item)
- {
- int index = findNextIndex(item);
- if (table[index] != null)
- {
- table[index].active = false;
- }
- }
-
- /**
- * Method to find the specified item in the hashTable
- *
- * @param item
- * @return the index at which the item is located, returns null if the item is not located in the hashTable
- */
- public Object find(Object item)
- {
- int index = findNextIndex(item);
- if (isActive(table[index]))
- {
- return table[index].elm;
- }
- return null;
- }
-
- /**
- * Counts the number of entries in the hashtable
- * @return an integer for the amount of items in a hashTable
- */
- public int elementCount()
- {
- int count = 0; // integer counting the amount of items in an object
- for (HashEntry he : table)
- {
- if (isActive(he))
- {
- count++;
- }
- }
- return count;
- }
-
- /**
- * Method seeing whether or not the hashTable is empty
- * @return true if the hashTable is empty, false if it is not
- */
- public boolean isEmpty()
- {
- for (HashEntry he : table)
- {
- if (isActive(he))
- {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Empties the hashTable of all elements
- */
- public void makeEmpty()
- {
- table = new HashEntry[table.length];
- }
-
- /**
- * Prints out the hashtable in the following format:
- * [0]: xxx, active
- *[1]: empty
- *[2]: yyy, inactive
- */
- public void printTable()
- {
- for (int i = 0; i < table.length; i++)
- {
- System.out.print("["+i+"]: ");
- if (table[i] == null)
- {
- System.out.print("empty");
- }
- else
- {
- System.out.print(table[i].elm);
- System.out.print(", ");
- System.out.print(table[i].active? "active":"inactive");
- }
- System.out.println();
- }
- }
- /**
- * Constructor creating a new iterator
- * @return a new Iterator
- */
- @SuppressWarnings("rawtypes")
- public Iterator iterator()
- {
- return new Iter();
- }
- }
|