w3resource

Basic Hash table implementation in C: Insertion, deletion, and retrieval

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

Write a C program that implements a basic hash table with functions for insertion, deletion, and retrieval of key-value pairs.

Sample Solution:

C Code:

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

// Define a structure to represent key-value pairs
struct KeyValuePair {
    char key[50];
    int value;
    struct KeyValuePair* next;
};

// Define a structure to represent the 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;
}

// Function to calculate the hash value of a key
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);
    struct KeyValuePair* newPair = createKeyValuePair(key, value);
    newPair->next = hashTable->table[index];
    hashTable->table[index] = newPair;
}

// Function to retrieve the value associated with a key from the hash table
int retrieve(struct HashTable* hashTable, const char* key) {
    unsigned int index = hashFunction(key, hashTable->size);
    struct KeyValuePair* current = hashTable->table[index];
    while (current != NULL) {
        if (strcmp(current->key, key) == 0) {
            return current->value;
        }
        current = current->next;
    }
    return -1; // Return -1 if the key is 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;

    while (current != NULL) {
        if (strcmp(current->key, key) == 0) {
            if (previous == NULL) {
                hashTable->table[index] = current->next;
            } else {
                previous->next = current->next;
            }

            free(current);
            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() {
    // Create a hash table with a size of 10
    struct HashTable* hashTable = createHashTable(10);

    // Insert key-value pairs into the hash table
    insert(hashTable, "Alaric", 35);
    insert(hashTable, "Faustus", 28);
    insert(hashTable, "Wilbur", 30);
    insert(hashTable, "Melcha", 31);

    // Display the initial state of the hash table
    printf("Initial Hash Table:\n");
    displayHashTable(hashTable);
    printf("\n");

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

    // Remove a key-value pair and display the updated hash table
    printf("Deleting key 'Faustus'\n");
    removeKey(hashTable, "Faustus");
    displayHashTable(hashTable);
    printf("\n");

    // Free the memory allocated for the hash table
    freeHashTable(hashTable);

    return 0;
}

Output:

Initial Hash Table:
[0] -> NULL
[1] -> (Faustus, 28) -> NULL
[2] -> NULL
[3] -> NULL
[4] -> NULL
[5] -> (Melcha, 31) -> NULL
[6] -> NULL
[7] -> NULL
[8] -> (Wilbur, 30) -> NULL
[9] -> (Alaric, 35) -> NULL

Value for key 'Alaric': 35
Value for key 'Faustus': 28
Value for key 'Cambria': -1

Deleting key 'Faustus'
[0] -> NULL
[1] -> NULL
[2] -> NULL
[3] -> NULL
[4] -> NULL
[5] -> (Melcha, 31) -> NULL
[6] -> NULL
[7] -> NULL
[8] -> (Wilbur, 30) -> NULL
[9] -> (Alaric, 35) -> NULL

Explanation:

In the exercise above,

  • Structures:
    • KeyValuePair: Represents a key-value pair with a key (string) and a value (integer), and a pointer to the next pair in case of collision.
    • HashTable: Represents a hash table with a specified size and an array of pointers to KeyValuePair.
  • Functions:
    • createKeyValuePair: Allocates memory for a new key-value pair and initializes its values.
    • createHashTable: Allocates memory for a new hash table with a specified size and initializes its array of pointers.
    • hashFunction: Calculates the hash value of a given key using a simple hashing algorithm.
    • insert: Inserts a new key-value pair into the hash table using the calculated hash value.
    • retrieve: Retrieves the value associated with a key from the hash table.
    • removeKey: Removes a key-value pair from the hash table.
    • displayHashTable: Displays the contents of the hash table, including chains in case of collisions.
    • freeHashTable: Frees the memory allocated for the hash table, including all key-value pairs.
  • Main Function:
    • Creates a hash table with a size of 10.
    • Inserts several key-value pairs into the hash table.
    • Displays the initial state of the hash table.
    • Retrieves and prints values for specific keys.
    • Removes a key-value pair and displays the updated hash table.
    • Frees the memory allocated for the hash table.

Flowchart:

Flowchart: Basic Hash table implementation in C: Insertion, deletion, and retrieval.
Flowchart: Basic Hash table implementation in C: Insertion, deletion, and retrieval.
Flowchart: Basic Hash table implementation in C: Insertion, deletion, and retrieval.
Flowchart: Basic Hash table implementation in C: Insertion, deletion, and retrieval.

C Programming Code Editor:

Previous: C Program: Hash Table Implementation and Operations Home.
Next: Hash Table in C with collision Handling: Insertion, deletion, retrieval.

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://www.w3resource.com/c-programming-exercises/hash/c-hash-exercises-1.php