Skip to content

Commit

Permalink
Merge pull request #1317 from Riya7045/main
Browse files Browse the repository at this point in the history
Added Hashmap data structure
  • Loading branch information
pankaj-bind authored Oct 30, 2024
2 parents addb547 + b08359e commit 9b7cd77
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 0 deletions.
144 changes: 144 additions & 0 deletions hashmap/Implementation.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#include <stdio.h>
#include <stdlib.h>

// Define the structure for a node in the linked list (for chaining)
typedef struct Node {
int key;
int value;
struct Node* next;
} Node;

// Define the structure for the Hashmap
typedef struct HashMap {
int size; // Size of the hashmap (number of buckets)
Node** buckets; // Array of pointers to the linked lists (buckets)
} HashMap;

// Create a new node (for the linked list)
Node* createNode(int key, int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = key;
newNode->value = value;
newNode->next = NULL;
return newNode;
}

// Create the HashMap
HashMap* createHashMap(int size) {
HashMap* map = (HashMap*)malloc(sizeof(HashMap));
map->size = size;
map->buckets = (Node**)malloc(size * sizeof(Node*));

// Initialize all buckets to NULL
for (int i = 0; i < size; i++) {
map->buckets[i] = NULL;
}

return map;
}

// Hash function to map a key to an index based on table size (modulo operator)
int hashFunction(int key, int size) {
return key % size;
}

// Insert a key-value pair into the HashMap
void insert(HashMap* map, int key, int value) {
int index = hashFunction(key, map->size);
Node* newNode = createNode(key, value);

// If there's no collision, insert the node at the bucket
if (map->buckets[index] == NULL) {
map->buckets[index] = newNode;
} else {
// Handle collision using chaining (linked list)
Node* current = map->buckets[index];
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
printf("Inserted key: %d, value: %d at index: %d\n", key, value, index);
}

// Search for a value by key in the HashMap
int search(HashMap* map, int key) {
int index = hashFunction(key, map->size);
Node* current = map->buckets[index];

while (current != NULL) {
if (current->key == key) {
return current->value;
}
current = current->next;
}

return -1; // Key not found
}

// Delete a key-value pair from the HashMap
void Delete(HashMap* map, int key) {
int index = hashFunction(key, map->size);
Node* current = map->buckets[index];
Node* prev = NULL;

while (current != NULL) {
if (current->key == key) {
if (prev == NULL) {
map->buckets[index] = current->next; // Remove head of the list
} else {
prev->next = current->next; // Bypass the node to delete it
}
free(current);
printf("Key %d deleted\n", key);
return;
}
prev = current;
current = current->next;
}

printf("Key %d not found\n", key);
}

// Free the memory used by the HashMap
void freeHashMap(HashMap* map) {
for (int i = 0; i < map->size; i++) {
Node* current = map->buckets[i];
while (current != NULL) {
Node* temp = current;
current = current->next;
free(temp);
}
}
free(map->buckets);
free(map);
}

// Main function to demonstrate the usage
int main() {
// Create a HashMap with 10 buckets
HashMap* map = createHashMap(10);

// Insert some key-value pairs
insert(map, 1, 10);
insert(map, 2, 20);
insert(map, 12, 120); // This will collide with key 2
insert(map, 22, 220); // Another collision example

// Search for a key
int value = search(map, 12);
if (value != -1) {
printf("Key 12 found with value: %d\n", value);
} else {
printf("Key 12 not found\n");
}

// Delete a key-value pair
Delete(map, 2);
Delete(map, 22);

// Free the memory used by the HashMap
freeHashMap(map);

return 0;
}
61 changes: 61 additions & 0 deletions hashmap/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# HashMap Implementation in C
This project is a simple implementation of a HashMap (or Hash Table) in C, using chaining to handle collisions.The implementation includes common HashMap operations
such as insertion, search, and deletion of key-value pairs. The chaining mechanism uses linked lists to resolve hash collisions.

## Features
Chaining-based collision handling: Handles collisions using linked lists in each bucket.

Hashing: Uses a simple modulo-based hash function.

Operations:

Insertion of key-value pairs.

Searching for a value by its key.

Deleting key-value pairs.

Memory management: Clean up memory to avoid memory leaks.

## 1. Insertion
The insertion operation involves adding a new key-value pair to the HashMap. The process is as follows:

Hashing: The key is hashed using the hash function. In this case, the hash function uses the modulo operation to map the key to a specific index in the bucket array:
The result of the hash function is the index in the bucket array where the key-value pair will be inserted.

Collision Handling: If two keys produce the same index (i.e., a collision occurs), the linked list at that bucket is extended to accommodate the new key-value pair.
This is called chaining. Each bucket points to the head of a linked list, and new nodes are added to the end of the list if there is a collision.

Time Complexity:
Best case (no collision): O(1)
Worst case (multiple collisions): O(n) where n is the number of nodes in the linked list (in the case of a very poor hash function or many collisions).

## 2. Deletion
The deletion operation removes a key-value pair from the HashMap by:

Hashing: The key to be deleted is hashed to find the index of the bucket.
Traversal: The linked list at the bucket is traversed to find the node that contains the given key.
Removal: Once the node with the given key is found:
If it's the head of the list, the bucket is updated to point to the next node.
If it's in the middle or at the end of the list, the previous node's next pointer is updated to bypass the node to be deleted.

Memory Deallocation: The memory allocated for the deleted node is freed.

Time Complexity:
Best case: O(1) (when the key is found immediately and there's no collision)
Worst case: O(n) (when multiple nodes are in the same bucket, and the key is found at the end)

## 3. Searching
Searching for a key in the HashMap involves:

Hashing: The key to be searched is hashed to find the index of the bucket.
Traversal: The linked list at the bucket is traversed, checking each node's key. If the key is found, the corresponding value is returned;
otherwise, a value of -1 (indicating "not found") is returned.

The linked list traversal continues until either:

The key is found, or
The end of the list is reached (in which case the key doesn't exist in the HashMap).
Time Complexity:
Best case: O(1) (if the key is at the head of the list or no collision occurred)
Worst case: O(n) (if there are multiple collisions, and the key is at the end of the list)

0 comments on commit 9b7cd77

Please sign in to comment.