w3resource

Hash Table in C with collision Handling: Insertion, deletion, retrieval

C Program to implement Hash Tables: Exercise-2 with Solution

Implement a basic hash table in C with functions for insertion, deletion, and retrieval of key-value pairs. Write a C program that extends the above basic hash table implementation to handle collisions using techniques such as chaining or open addressing.

Sample Solution:

C Code:

// Including necessary header files
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Structure to represent a key-value pair
struct KeyValuePair {
    char key[50];
    int value;
    struct KeyValuePair* next;
};

// Structure to represent a hash table
struct HashTable {
    int size;
    struct KeyValuePair** table;
};

// Function to create a new key-value pair
struct KeyValuePair* createKeyValuePair(const char* key, int value) {
    struct KeyValuePair* newPair = (struct KeyValuePair*)malloc(sizeof(struct KeyValuePair));
    if (newPair != NULL) {
        strcpy(newPair->key, key);
        newPair->value = value;
        newPair->next = NULL;
    }
    return newPair;
}

// Function to create a new hash table
struct HashTable* createHashTable(int size) {
    struct HashTable* newTable = (struct HashTable*)malloc(sizeof(struct HashTable));
    if (newTable != NULL) {
        newTable->size = size;
        newTable->table = (struct KeyValuePair**)calloc(size, sizeof(struct KeyValuePair*));
    }
    return newTable;
}

// Hash function to calculate the index
unsigned int hashFunction(const char* key, int tableSize) {
    unsigned int hash = 0;
    while (*key) {
        hash = (hash << 5) + *key++;
    }
    return hash % tableSize;
}

// Function to insert a key-value pair into the hash table
void insert(struct HashTable* hashTable, const char* key, int value) {
    unsigned int index = hashFunction(key, hashTable->size);
    
    // Create a new key-value pair
    struct KeyValuePair* newPair = createKeyValuePair(key, value);
    
    // Insert the new pair at the beginning of the linked list
    newPair->next = hashTable->table[index];
    hashTable->table[index] = newPair;
}

// Function to retrieve the value associated with a key
int retrieve(struct HashTable* hashTable, const char* key) {
    unsigned int index = hashFunction(key, hashTable->size);
    struct KeyValuePair* current = hashTable->table[index];
    
    // Traverse the linked list at the index
    while (current != NULL) {
        if (strcmp(current->key, key) == 0) {
            return current->value; // Key found, return the value
        }
        current = current->next;
    }
    return -1; // Key not found
}

// Function to remove a key-value pair from the hash table
void removeKey(struct HashTable* hashTable, const char* key) {
    unsigned int index = hashFunction(key, hashTable->size);
    struct KeyValuePair* current = hashTable->table[index];
    struct KeyValuePair* previous = NULL;

    // Traverse the linked list at the index
    while (current != NULL) {
        if (strcmp(current->key, key) == 0) {
            if (previous == NULL) {
                hashTable->table[index] = current->next; // Update head if it's the first node
            } else {
                previous->next = current->next; // Update pointers to remove the current node
            }

            free(current); // Free memory for the removed node
            return;
        }

        previous = current;
        current = current->next;
    }
}

// Function to display the contents of the hash table
void displayHashTable(struct HashTable* hashTable) {
    for (int i = 0; i < hashTable->size; i++) {
        printf("[%d] -> ", i);

        struct KeyValuePair* current = hashTable->table[i];
        while (current != NULL) {
            printf("(%s, %d) -> ", current->key, current->value);
            current = current->next;
        }

        printf("NULL\n");
    }
}

// Function to free the memory allocated for the hash table
void freeHashTable(struct HashTable* hashTable) {
    for (int i = 0; i < hashTable->size; i++) {
        struct KeyValuePair* current = hashTable->table[i];
        while (current != NULL) {
            struct KeyValuePair* temp = current;
            current = current->next;
            free(temp);
        }
    }

    free(hashTable->table);
    free(hashTable);
}

// Main function
int main() {
    struct HashTable* hashTable = createHashTable(10);

    // Insert key-value pairs
    insert(hashTable, "Endymion", 35);
    insert(hashTable, "Clover", 38);
    insert(hashTable, "Khazhak", 35);
    insert(hashTable, "Melcha", 41);
    insert(hashTable, "Taqqiq", 42); // Collision with "Endymion"
    insert(hashTable, "Ufuoma", 55); // Collision with "Khazhak"
    
    printf("Initial Hash Table:\n");
    displayHashTable(hashTable);
    printf("\n");

    // Retrieve and print values for specific keys
    printf("Value for key 'Endymion': %d\n", retrieve(hashTable, "Endymion"));
    printf("Value for key 'Taqqiq': %d\n", retrieve(hashTable, "Taqqiq"));
    printf("Value for key 'Faustus': %d\n", retrieve(hashTable, "Faustus"));
    printf("\n");

    // Remove a key-value pair
    printf("Deleting key 'Clover'\n");
    removeKey(hashTable, "Clover");
    displayHashTable(hashTable);
    printf("\n");

    // Free allocated memory
    freeHashTable(hashTable);

    return 0;
}

Output:

Initial Hash Table:
[0] -> NULL
[1] -> NULL
[2] -> (Endymion, 35) -> NULL
[3] -> NULL
[4] -> NULL
[5] -> (Melcha, 41) -> NULL
[6] -> NULL
[7] -> (Ufuoma, 55) -> NULL
[8] -> (Clover, 38) -> NULL
[9] -> (Taqqiq, 42) -> (Khazhak, 35) -> NULL

Value for key 'Endymion': 35
Value for key 'Taqqiq': 42
Value for key 'Faustus': -1

Deleting key 'Clover'
[0] -> NULL
[1] -> NULL
[2] -> (Endymion, 35) -> NULL
[3] -> NULL
[4] -> NULL
[5] -> (Melcha, 41) -> NULL
[6] -> NULL
[7] -> (Ufuoma, 55) -> NULL
[8] -> NULL
[9] -> (Taqqiq, 42) -> (Khazhak, 35) -> NULL

Explanation:

In the exercise above,

  • Structures:
    • KeyValuePair: Represents a key-value pair with a key (string), value (integer), and a pointer to the next KeyValuePair (for handling collisions).
    • HashTable: Represents a hash table with a specified size and an array of pointers to KeyValuePairs.
  • Functions:
    • createKeyValuePair: Creates a new key-value pair and initializes its members.
    • createHashTable: Creates a new hash table and allocates memory for the array of pointers.
    • hashFunction: Calculates the index for a key using a simple hash function.
    • insert: Inserts a key-value pair into the hash table, handling collisions using chaining.
    • retrieve: Retrieves the value associated with a given key from the hash table.
    • removeKey: Removes a key-value pair from the hash table.
    • displayHashTable: Displays the contents of the hash table, including linked lists for collisions.
    • freeHashTable: Frees the memory allocated for the hash table.
  • Main Function:
    • Creates a hash table with a size of 10.
    • Inserts several key-value pairs into the hash table, intentionally causing collisions.
    • Displays the initial state of the hash table.
    • Retrieves and prints values for specific keys.
    • Deletes a key-value pair.
    • Displays the updated hash table.
    • Frees allocated memory.

Flowchart:

Flowchart: Hash Table in C with collision Handling: Insertion, deletion, retrieval.
Flowchart: Hash Table in C with collision Handling: Insertion, deletion, retrieval.
Flowchart: Hash Table in C with collision Handling: Insertion, deletion, retrieval.
Flowchart: Hash Table in C with collision Handling: Insertion, deletion, retrieval.

C Programming Code Editor:

Previous: Basic Hash table implementation in C: Insertion, deletion, and retrieval.
Next: C Program: String Hash function and Hash table.

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Become a Patron!

Follow us on Facebook and Twitter for latest update.

It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.

https://w3resource.com/c-programming-exercises/hash/c-hash-exercises-2.php