INTRODUCTION TO HASHING
WHATIS HASHING?
COMPONENTS OF HASHING
Hashing is a technique for mapping data to a fixed-size value (hash value) using a hash function.
Key: Data item to be stored or retrieved.
The primary use is to enable fast data retrieval, insertion, and deletion.
Hash Function: Transforms the key into a hash value.
Common use cases: hash tables, caching, indexing, and cryptography.
Hash Table: A data structure storing the keys and associated values.
Collision: When two keys map to the same hash value.
3.
INTRODUCTION TO HASHING
HASHFUNCTION:
HASH FUNCTIONS:
CODE EXAMPLE: CALL THIS FUNCTION AS:
42%10 = 2 OUTPUT: 2
1. MODULO OPERATION: INDEX=KEY%TABLE SIZE
2. MULTIPLICATIVE HASHING: INDEX= (KEY×AMOD1)×TABLE SIZE ,
⌊ ⌋ WHERE A IS A CONSTANT.
3. STRING HASHING:
A function that converts input (keys) into a fixed-size integer (hash).
Converts strings into unique hash codes using ASCII values or polynomial rolling.
int hashFunction(int key, int tableSize) {
return key % tableSize; // Simple Modulo Division }
int result hashFunction(42, 10);
Example: h(k) = k % N (modulus operation for a hash table size N).
4.
COLLISION:
HASH TABLES AND
COLLISIONHANDLING
A data structure that stores key-value pairs, indexed by
the hash of the key.
Occurs when two different keys produce the same hash
value.
Store multiple keys of the same hash values in the same
index using a linked list.
This code does not generate direct output to the console or a
file. Instead, it modifies the state of the table array, inserting
nodes into the appropriate chains.
COLLISION HANDLING METHODS
1. CHAINING (SEPARATE CHAINING)
HASH TABLE: CODE EXAMPLE (CHAINING):
OUTPUT BEHAVIOUR:
struct Node {
int key;
Node* next;
};
void insert(Node* table[], int key, int tableSize) {
int index = key % tableSize;
Node* newNode = new Node{key, table[index]};
table[index] = newNode;
}
5.
TYPES:
HASH TABLES AND
COLLISIONHANDLING
Linear Probing: Increment index sequentially to find an
empty slot.
Quadratic probing: Increment index quadratically.
Double Hashing: Two hash functions to determine the
next slot.
Formula: Index=(Key+C1 i+C2 i2)%Table Size
⋅ ⋅
Formula: Index=(Hash1+Probe Hash2)%Table Size
⋅
• All keys are stored directly in the hash table by
probing for the next available slot.
The output of this code will be the index of the first empty
slot for a given key, determined using linear probing.
2. OPEN ADDRESSING CODE EXAMPLE (LINEAR PROBING):
OUTPUT BEHAVIOUR:
int linearProbe(int table[], int tableSize, int key) {
int index = key % tableSize;
while (table[index] != -1) { // -1 indicates an empty slot
index = (index + 1) % tableSize;
}
return index;
}
6.
HASHING FOR STRINGS
CODEEXAMPLE:
#include <iostream>
using namespace std;
int stringHash(string s, int prime, int tableSize) {
int hash = 0;
int p = 1;
for (char c : s) {
hash = (hash + (c - 'a' + 1) * p) % tableSize;
p = (p * prime) % tableSize;
}
return hash;
}
int main() {
string s = "abc";
int prime = 31;
int tableSize = 10;
cout << "Hash value: " << stringHash(s, prime, tableSize) <<
endl;
return 0;
OUTPUT:
For the string “abc”, the output will be:
Hash value: 6
7.
HASHING WITH ARRAYS
•Suitable for simple implementations.
Using Arrays for Hash Tables: Assume we insert the following keys:
15, 25, 35, 45, 55.
After inserting the keys, the hash
table will look like this:
Example of storing integers using modulo hash
function:
CODE EXAMPLE:
const int TABLE_SIZE = 10;
int hashTable[TABLE_SIZE] = {-1}; // Initialize with -1 for empty
slots
void insert(int key) {
int index = key % TABLE_SIZE;
while (hashTable[index] != -1) {
index = (index + 1) % TABLE_SIZE; // Linear probing
}
hashTable[index] = key;
}
Index 0: -1
Index 1: -1
Index 2: -1
Index 3: -1
Index 4: -1
Index 5: 15
Index 6: 25
Index 7: 35
Index 8: 45
Index 9: 55
8.
HASHING WITH LINKED
LIST
•Handles collisions more effectively.
Using Linked Lists for Chaining: Assume we insert the following keys:
15, 25, 35, 45, 55.
After inserting the keys, the hash
table will look like this:
CODE EXAMPLE:
const int TABLE_SIZE = 10;
struct Node {
int key;
Node* next;
};
Node* hashTable[TABLE_SIZE] = {nullptr};
void insert(int key) {
int index = key % TABLE_SIZE;
Node* newNode = new Node{key,
hashTable[index]};
hashTable[index] = newNode;
}
Index 0: Empty
Index 1: Empty
Index 2: Empty
Index 3: Empty
Index 4: Empty
Index 5: 55 -> 45 -> 35 -> 25 -> 15
Index 6: Empty
Index 7: Empty
Index 8: Empty
Index 9: Empty
9.
CONCLUSION: HASHING INC++
Hashing is a technique to map data to a fixed-size value using a hash function, allowing for efficient data retrieval, insertion, and deletion.
Hashing plays a crucial role in optimizing data access and storage in many computer science applications.
A good hash function is key to minimizing collisions and improving performance.
Understanding different collision resolution techniques (e.g., chaining, open addressing) is vital for effective use of hashing in real-world problems.
Fast data lookup by mapping
keys to values
Efficient implementation of
sets, maps, and dictionaries
Ensures data integrity using hash
functions like MD5 and SHA.
Used in digital signatures
and password hashing.
Stores frequently accessed
data for faster retrieval.
A hash table stores keys and values, with the hash function determining the index in the table.
Collisions occur when two keys map to the same index. This can be resolved using methods like chaining (linked lists) and open
addressing (e.g., linear probing).
RECAP OF KEY CONCEPTS:
APPLICATIONS OF HASHING:
FINAL THOUGHTS:
DATABASE INDEXING
HASH TABLES DATA INTEGRITY
CRYPTOGRAPHY CACHING