Definition
Hash Search is a searching technique that uses a hash function to map keys to specific indices in a hash table, allowing constant-time search operations in most cases.
It is one of the most efficient search methods for large datasets when implemented correctly.


📌 1. Purpose and Use Cases

  • Fast searching is required in the average case).
  • ✅ The dataset is large and frequently accessed.
  • ✅ Insertions, deletions, and searches need to be fast.
  • Random access to elements is needed.
  • ❌ When ordered data is required (e.g., range queries, sorted output).
  • ❌ The dataset size is too small, making a hash table unnecessary.
  • ❌ If collisions are not well handled, performance may degrade to .
  • ❌ When searching in linked lists or structures without index-based access.

📌 2. Implementation

Hashing Concept

A hash function maps a key to an index in a hash table of size :

Handling Collisions

Collisions occur when two keys map to the same index. Common techniques to handle collisions:

  • Chaining (Linked List at each index)
  • Open Addressing (e.g., Linear Probing, Quadratic Probing, Double Hashing)

📌 Hash Search Implementation in Java

Chaining (Separate Linked List)

import java.util.LinkedList;
 
class HashTable {
    private static final int SIZE = 10;
    private LinkedList<Integer>[] table;
 
    public HashTable() {
        table = new LinkedList[SIZE];
        for (int i = 0; i < SIZE; i++) {
            table[i] = new LinkedList<>();
        }
    }
 
    private int hashFunction(int key) {
        return key % SIZE;
    }
 
    public void insert(int key) {
        int index = hashFunction(key);
        table[index].add(key);
    }
 
    public boolean search(int key) {
        int index = hashFunction(key);
        return table[index].contains(key);
    }
 
    public void remove(int key) {
        int index = hashFunction(key);
        table[index].remove((Integer) key);
    }
 
    public static void main(String[] args) {
        HashTable ht = new HashTable();
        ht.insert(10);
        ht.insert(20);
        ht.insert(30);
 
        System.out.println(ht.search(20)); // Output: true
        System.out.println(ht.search(40)); // Output: false
    }
}

📌 Open Addressing with Linear Probing

class HashTableLinearProbing {
    private static final int SIZE = 10;
    private Integer[] table;
 
    public HashTableLinearProbing() {
        table = new Integer[SIZE];
    }
 
    private int hashFunction(int key) {
        return key % SIZE;
    }
 
    public void insert(int key) {
        int index = hashFunction(key);
        while (table[index] != null) { 
            index = (index + 1) % SIZE; // Linear probing
        }
        table[index] = key;
    }
 
    public boolean search(int key) {
        int index = hashFunction(key);
        int start = index;
        while (table[index] != null) {
            if (table[index] == key) return true;
            index = (index + 1) % SIZE;
            if (index == start) return false;
        }
        return false;
    }
 
    public void remove(int key) {
        int index = hashFunction(key);
        while (table[index] != null) {
            if (table[index] == key) {
                table[index] = null;
                return;
            }
            index = (index + 1) % SIZE;
        }
    }
}

📌 3. Complexity Analysis

Time Complexity

CaseComplexityExplanation
🟢 Best CaseNo collisions, direct access.
🟡 Average CaseWith a well-distributed hash function, search is nearly constant-time.
🔴 Worst CaseAll elements collide into a single bucket, degrading to linear search.

Space Complexity

  • Chaining: (extra space required for linked lists).
  • Open Addressing: (all elements stored directly in the table).

📌 4. Advantages and Disadvantages

Advantages

✔️ Extremely fast search, insert, and delete operations in the average case).
✔️ Ideal for large datasets with frequent access.
✔️ Does not require sorting of data.
✔️ Can store key-value pairs (like dictionaries in Python or HashMaps in Java).

Disadvantages

Collisions degrade performance if not handled properly.
Does not maintain order, making range queries inefficient.
Requires a good hash function to distribute keys evenly.
Resizing is expensive (when the load factor exceeds a threshold, rehashing is required).


📌 5. Types of Hash Functions

Hash FunctionFormulaNotes
Modulo HashingSimple, works best when is a prime number.
Multiplicative HashingA is typically (golden ratio).
Universal HashingUses a random prime , good for cryptographic applications.

📌 6. Chaining vs. Open Addressing

FeatureChaining (Linked Lists)Open Addressing
Space Complexity
Search PerformanceGood when the load factor is lowDegrades with high load factor
Insert PerformanceFast, but extra memory neededSlower when the table is full
Load Factor HandlingCan exceed 1Must be to maintain efficiency

ScenarioBest Algorithm
Fast lookup required✅ Hash Search
Data needs to be sorted❌ Binary Search
Unsorted, small dataset❌ Sequential Search
Key-value storage required✅ Hash Tables
Handling dynamic data✅ Hashing with chaining

📌 8. Summary

  • Hash Search is one of the fastest search methods available, with an average-case complexity of .
  • It is ideal for large datasets where fast lookup is needed.
  • Collisions must be handled properly using chaining or open addressing.
  • Does not maintain order, making it unsuitable for range-based queries.