Skillversitas

Hash Table

A Hash Table is a data structure that stores key-value pairs. It uses a hash function to compute an index from the key, enabling O(1) average-case access.

Core Concept

Key -> Hash Function -> Index -> Value
"name" -> hash("name") -> 3 -> "John"

Hash Function

A hash function converts a key into an array index. A good hash must be:
- Consistent: the same input always produces the same result.
- Uniform: distributes keys evenly across all indices.
- Fast: computed in O(1) time.

# Simple hash function
def simple_hash(key, size):
    return hash(key) % size

Collision Resolution

When two keys produce the same hash, a collision occurs.

1. Chaining

Each slot holds a linked list. Collisions are appended to the linked list.

class HashTableChaining:
    def __init__(self, size=16):
        self.size = size
        self.table = [[] for _ in range(size)]

    def _hash(self, key):
        return hash(key) % self.size

    def put(self, key, value):
        idx = self._hash(key)
        for i, (k, v) in enumerate(self.table[idx]):
            if k == key:
                self.table[idx][i] = (key, value)
                return
        self.table[idx].append((key, value))

    def get(self, key):
        idx = self._hash(key)
        for k, v in self.table[idx]:
            if k == key:
                return v
        raise KeyError(key)

    def delete(self, key):
        idx = self._hash(key)
        for i, (k, v) in enumerate(self.table[idx]):
            if k == key:
                del self.table[idx][i]
                return
        raise KeyError(key)

2. Open Addressing

Collisions are resolved by looking for the next slot in the same array.

Method Description
Linear Probing Check the next slot sequentially
Quadratic Probing Probing distances: 1², 2², 3², ...
Double Hashing Use a second hash function

Load Factor and Rehashing

Load factor = number of elements / table size. When the load factor exceeds a threshold (usually 0.75), rehashing is performed: a larger new table is created and all elements are moved into it.

Python dict and Java HashMap

# Python dict (Hash Table)
person = {"name": "John", "age": 25}
person["city"] = "New York"
print(person["name"])  # John
del person["age"]
// Java HashMap
import java.util.HashMap;

HashMap<String, Integer> map = new HashMap<>();
map.put("name", 1);
map.get("name");      // 1
map.containsKey("x"); // false

Time Complexity

Operation Average Worst
Insert O(1) O(n)
Search O(1) O(n)
Delete O(1) O(n)

The O(n) worst case happens when all keys collide (rare with a good hash function).

Use Cases

  • Database indexing
  • Cache (memoization)
  • Symbol table in compilers
  • Frequency counting
  • Anagram grouping

Hash Tables are very fast for key-based access. Now let's study Binary Trees for hierarchical data.