Hash Table
Hash tables, also known as hash maps, are a fundamental data structure used to store and retrieve key-value pairs efficiently. They play a crucial role in many programming tasks, ranging from optimizing search operations to implementing dictionaries and sets. In this blog post, we'll explore the concept of hash tables, how they work, and how to implement and use them in JavaScript.
Why Use Hash Tables?
Hash tables provide constant-time average-case performance for basic operations like insertion, deletion, and retrieval. They are commonly used for tasks that involve quick lookups or maintaining relationships between items.
Hashing Functions:
How Hashing Works
A hashing function takes an input (usually a key) and converts it into a fixed-size value (hash code) that represents the input. This hash code is used as an index to store or retrieve data in the array.
Properties of Good Hash Functions
A good hash function should:
Produce unique hash codes for distinct inputs.
Distribute hash codes uniformly to avoid clustering.
Be efficient to compute.
Implementing a Hash Table
Creating the Hash Table Class
We'll create a simple hash table class using an array to store key-value pairs. Here's a basic implementation:
class HashTable {
constructor(size = 100) {
this.size = size;
this.data = new Array(size);
}
_hash(key) {
let hash = 0;
for (let i = 0; i < key.length; i++) {
hash = (hash + key.charCodeAt(i)) % this.size;
}
return hash;
}
set(key, value) {
const index = this._hash(key);
if (!this.data[index]) {
this.data[index] = [];
}
this.data[index].push([key, value]);
}
get(key) {
const index = this._hash(key);
const bucket = this.data[index];
if (bucket) {
for (const pair of bucket) {
if (pair[0] === key) {
return pair[1];
}
}
}
return undefined;
}
Handling Collisions
Collisions occur when two different keys hash to the same index. In our example, we handle collisions using separate chaining, where each index in the array holds a bucket (an array) of key-value pairs.
Resolving Collisions: Separate Chaining and Open Addressing
Separate Chaining: Each index contains a linked list (or another data structure) to store multiple key-value pairs that hash to the same index.
Open Addressing: In case of collisions, the algorithm searches for the next available slot in the array to place the value.
Using Hash Tables
Adding and Retrieving Elements
const myHashTable = new HashTable();
myHashTable.set('name', 'Irfan');
myHashTable.set('age', 21);
console.log(myHashTable.get('name')); // Output: Irfan
console.log(myHashTable.get('age')); // Output: 21
Removing Elements
myHashTable.remove('age'); // Implement the remove method in HashTable class
console.log(myHashTable.get('age')); // Output: undefined
Checking for the Presence of a Key
javascriptCopy codeconsole.log(myHashTable.hasKey('name')); // Output: true
console.log(myHashTable.hasKey('gender')); // Output: false
Hash Table Applications
Caching:
Hash tables are used in caching systems to store frequently accessed data for faster retrieval.
Frequency Counting:
Hash tables can be used to count the frequency of elements in a collection.
Grouping and Counting:
Hash tables can help group and count elements based on certain criteria.
Performance Analysis
Time Complexity
Average-case time complexity for insertion, deletion, and retrieval is O(1).
Worst-case time complexity can degrade to O(n) if there are many collisions.
Space Complexity
- The space complexity is O(n), where n is the number of elements in the hash table.
Handling Hash Function Collisions
- Good hash functions and collision resolution techniques are crucial for maintaining performance.
in PrOgres.....
Hash tables can be used to count the frequency of elements in a collection.
conclusion:
Hash tables are a powerful and versatile data structure that enables efficient storage and retrieval of key-value pairs ,where keys are unique and used to retrieve values efficiently. They find applications in various programming tasks, from optimizing search operations to implementing complex data structures. It uses a hashing function to map keys to indices in an array, allowing for fast insertion, deletion, and retrieval of data.