12. Hash Table

Hashing Steps

Object -> int -> hashtable (array)

  1. Convert (Object -> int): hashCode()
  2. Compress (int -> hashtable (array)): Modulus(%)

Hash Table Operations

Hash Table Implementation

public class HashTable implements HashTableInterface { private static final DataItem DELETED = new DataItem(-1); private DataItem[] hashArray; public HashTable(int initialCapacity) { hashArray = new DataItem[initialCapacity]; } /** * Returns true when the key is found. * @param key to search for * @return true if found, false if not found */ @Override public boolean search(int key) { int hashVal = hashFunc(key); while (hashArray[hashVal] != null) { // If the key is found if (hashArray[hashVal].key == key) { return true; } // Linear probing with step size of 1 hashVal = hashVal + 1; hashVal = hashVal % hashArray.length; } return false; } /** * Deletes and returns the int key found in the table. * @param key to delete * @return deleted int from the table (if not found, -1) */ @Override public int delete(int key) { int hashVal = hashFunc(key); while (hashArray[hashVal] != null) { // If the key is found if (hashArray[hashVal].key == key) { DataItem item = hashArray[hashVal]; hashArray[hashVal] = DELETED; return item.key; } // Linear probing with step size of 1 hashVal = hashVal + 1; hashVal = hashVal % hashArray.length; } return -1; } /** * Inserts a positive int key to the table. * @param key to insert (positive and unique) */ @Override public void insert(int key) { int hashVal = hashFunc(key); // Search for an empty slot or a reusable slot, flagged as DELETED while ((hashArray[hashVal] != null) && (hashArray[hashVal] != DELETED)) { // Linear probing with step size of 1 hashVal = hashVal + 1; hashVal = hashVal % hashArray.length; } hashArray[hashVal] = new DataItem(key); } /** * Rudimentary modular hashing function. * @param key for which hash value need to be calculated (only positive integers) * @return index/hash value of the specified key */ private int hashFunc(int key) { return key % hashArray.length; } /** * Static nested class for DataItem. */ private static class DataItem { private int key; DataItem(int k) { key = k; } } }

Aspects of Hash Functions

  1. Deterministic

  2. Randomness

    1. Quick computation - Machine-dependent
    2. Evenly distributed - Data-dependent

Randomness

1. Random key values

index = key % hashArray.length;

2. Non-Random key values

Example: Car-part number

Generate a range of more random numbers

  1. Remove Non-Data:

  2. Use All Data: Incorporate all available data, avoiding truncation of key values.

  3. Use Prime Number for Modulo Base: Select a prime number as the modulo base (hash table length), which prevents clustering of keys that are multiples of the base, promoting a more uniform distribution of hash values.

  4. Use Folding: Divide keys into groups of digits and summing up the groups, which enhances randomness and reduces collisions in the hash table.


Back to Home Next Lecture