C Program To Implement Dictionary Using Hashing Algorithms May 2026

We need three primary structures:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// --- Configuration ---
#define TABLE_SIZE 100
// --- Data Structures ---
// 1. The Key-Value Pair Node
typedef struct KeyValue 
    char *key;
    int value;
    struct KeyValue *next; // For collision chaining
 KeyValue;
// 2. The Dictionary Structure
typedef struct Dictionary 
    KeyValue **table; // Array of pointers to KeyValue nodes
    int size;
    int count;       // Number of elements currently stored
 Dictionary;
// --- Hash Function ---
// djb2 Hash Function
unsigned long hash(const char *str) 
    unsigned long hash = 5381;
    int c;
    while ((c = *str++))
        hash = ((hash << 5) + hash) + c; // hash * 33 + c
    return hash % TABLE_SIZE;
// --- Memory Helpers ---
// Helper to duplicate string (C99 standard has strdup, but this is portable)
char* duplicate_string(const char *src) 
    char *dst = malloc(strlen(src) + 1);
    if (dst) strcpy(dst, src);
    return dst;
// --- Dictionary Operations ---
// 1. Initialization
Dictionary* create_dictionary() 
    Dictionary *dict = (Dictionary*)malloc(sizeof(Dictionary));
    dict->size = TABLE_SIZE;
    dict->count = 0;
// Allocate memory for the array of pointers and initialize to NULL
    dict->table = (KeyValue**)calloc(TABLE_SIZE, sizeof(KeyValue*));
return dict;
// 2. Insertion / Update
void insert(Dictionary *dict, const char *key, int value) 
    unsigned long index = hash(key);
KeyValue *current = dict->table[index];
// Case A: Key exists? Update the value.
    while (current != NULL) 
        if (strcmp(current->key, key) == 0) 
            current->value = value;
            return;
current = current->next;
// Case B: Key does not exist. Create a new node.
    KeyValue *new_node = (KeyValue*)malloc(sizeof(KeyValue));
    new_node->key = duplicate_string(key);
    new_node->value = value;
// Insert at the head of the linked list (O(1) prepend)
    new_node->next = dict->table[index];
    dict->table[index] = new_node;
    dict->count++;
// 3. Search / Lookup
// Returns pointer to value so we can check for NULL if key not found
int* get(Dictionary *dict, const char *key) 
    unsigned long index = hash(key);
    KeyValue *current = dict->table[index];
while (current != NULL) 
        if (strcmp(current->key, key) == 0) 
            return &(current->value); // Return address of value
current = current->next;
return NULL; // Key not found
// 4. Deletion
void delete_key(Dictionary *dict, const char *key) 
    unsigned long index = hash(key);
    KeyValue *current = dict->table[index];
    KeyValue *prev = NULL;
while (current != NULL) 
        if (strcmp(current->key, key) == 0) 
            if (prev == NULL) 
                // Node is at the head
                dict->table[index] = current->next;
             else 
                // Node is in the middle or end
                prev->next = current->next;
free(current->key);
            free(current);
            dict->count--;
            return;
prev = current;
        current = current->next;
printf("Key '%s' not found.\n", key);
// 5. Cleanup
void free_dictionary(Dictionary *dict) 
    for (int i = 0; i < dict->size; i++) 
        KeyValue *current = dict->table[i];
        while (current != NULL) 
            KeyValue *temp = current;
            current = current->next;
            free(temp->key);
            free(temp);
free(dict->table);
    free(dict);
// 6. Utility: Print Dictionary
void print_dictionary(Dictionary *dict) 
    printf("\n--- Dictionary Contents ---\n");
    for (int i = 0; i < dict->size; i++) 
        KeyValue *current = dict->table[i];
        if (current != NULL) 
            printf("Index [%d]: ", i);
            while (current != NULL) 
                printf("(%s: %d) -> ", current->key, current->value);
                current = current->next;
printf("NULL\n");
printf("---------------------------\n");
// --- Main Driver ---
int main() 
    Dictionary *myDict = create_dictionary();
// Insertions
    insert(myDict, "apple", 10);
    insert(myDict, "banana", 20);
    insert(myDict, "cherry", 30);
// Update
    insert(myDict, "apple", 15); // Update apple's value
// Lookup
    int *val = get(myDict, "banana");
    if (val) printf("Get 'banana': %d\n", *val);
val = get(myDict, "grape");
    if (!val) printf("Get 'grape': Key not found.\n");
// Print all to see structure
    print_dictionary(myDict);
// Deletion
    printf("Deleting 'banana'...\n");
    delete_key(myDict, "banana");
print_dictionary(myDict);
// Cleanup
    free_dictionary(myDict);
return 0;

In the realm of computer science, a dictionary (also known as a map, symbol table, or associative array) is one of the most fundamental and versatile data structures. It allows you to store key-value pairs and retrieve values in near-constant time, regardless of the size of the data. While languages like Python, Java, and C++ have built-in dictionary implementations (e.g., dict, HashMap, std::unordered_map), the C programming language does not provide a standard one. This forces C developers to implement their own dictionary from scratch. c program to implement dictionary using hashing algorithms

The most efficient way to implement a dictionary in C is by using hashing algorithms. This article provides an exhaustive guide to building a robust dictionary using hashing, covering everything from the theory of hash functions to collision resolution strategies, complete with a fully functional C implementation. We need three primary structures: #include &lt;stdio


Resizing involves creating a new larger bucket array, rehashing all entries, and freeing the old structure. In the realm of computer science, a dictionary

void resize_dictionary(Dictionary *dict) 
    unsigned long old_size = dict->size;
    Entry **old_buckets = dict->buckets;
// Double the size
dict->size *= 2;
dict->buckets = (Entry**)calloc(dict->size, sizeof(Entry*));
dict->count = 0; // Will be rebuilt
// Rehash all entries
for (unsigned long i = 0; i < old_size; i++) 
    Entry *curr = old_buckets[i];
    while (curr) 
        Entry *next = curr->next;
        unsigned long new_index = dict->hash_func(curr->key) % dict->size;
        curr->next = dict->buckets[new_index];
        dict->buckets[new_index] = curr;
        dict->count++;
        curr = next;
free(old_buckets);