C Program To Implement Dictionary Using Hashing Algorithms Official

strncpy(new_entry->key, key, MAX_KEY_LEN - 1); new_entry->key[MAX_KEY_LEN - 1] = '\0'; strncpy(new_entry->value, value, MAX_VALUE_LEN - 1); new_entry->value[MAX_VALUE_LEN - 1] = '\0';

// Key not found – create new entry (head insertion) Entry *new_entry = (Entry*)malloc(sizeof(Entry)); if (!new_entry) return;

This approach ensures that inserting an existing key becomes an update, while a new key is added without duplicates.

return NULL;

--- Dictionary contents (total 2 entries) --- Index 3: ('banana', 12) -> NULL Index 92: ('apple', 5) -> NULL

One of the most efficient ways to implement a dictionary is through . Hashing uses a hash function to map a key directly to the location where its corresponding value is stored. When implemented correctly, hashing yields average constant time ( O(1) ) for the basic operations, making it exceptionally fast.

case 5: printf("Total number of entries: %d\n", dict->count); break; c program to implement dictionary using hashing algorithms

printf("----------------------------------------------\n\n");

A good hash function distributes keys uniformly across the storage array. Uniform distribution minimizes collisions, which occur when two different keys generate the same index. For strings, polynomial rolling hash functions are highly effective. Collision Resolution

#define DEFAULT_SIZE 101 /* Prime number for better distribution */ For strings, polynomial rolling hash functions are highly

#include #include #include #define TABLE_SIZE 10007 // A prime number minimizes collision rates // Structure for a key-value pair node typedef struct Node char *key; int value; struct Node *next; Node; // Structure for the Dictionary Hash Table typedef struct Dictionary Node *buckets[TABLE_SIZE]; Dictionary; // 1. The DJB2 Hashing Algorithm unsigned long hash_function(const char *str) unsigned long hash = 5381; int c; while ((c = *str++)) hash = ((hash << 5) + hash) + c; // hash * 33 + c return hash % TABLE_SIZE; // 2. Initialize an empty dictionary Dictionary* create_dictionary() Dictionary *dict = (Dictionary*) malloc(sizeof(Dictionary)); if (dict == NULL) fprintf(stderr, "Memory allocation failed for Dictionary\n"); exit(EXIT_FAILURE); for (int i = 0; i < TABLE_SIZE; i++) dict->buckets[i] = NULL; return dict; // Helper to create a new node Node* create_node(const char *key, int value) Node *new_node = (Node*) malloc(sizeof(Node)); if (new_node == NULL) fprintf(stderr, "Memory allocation failed for Node\n"); exit(EXIT_FAILURE); new_node->key = strdup(key); // Allocate and copy string new_node->value = value; new_node->next = NULL; return new_node; // 3. Insert or Update a key-value pair void insert(Dictionary *dict, const char *key, int value) unsigned long index = hash_function(key); Node *current = dict->buckets[index]; // Check if key already exists to update its value while (current != NULL) if (strcmp(current->key, key) == 0) current->value = value; // Update existing key return; current = current->next; // Key does not exist; insert new node at the head of the chain Node *new_node = create_node(key, value); new_node->next = dict->buckets[index]; dict->buckets[index] = new_node; // 4. Lookup a value by its key // Returns 1 if found (stores result in output pointer), 0 if not found int lookup(Dictionary *dict, const char *key, int *output_value) unsigned long index = hash_function(key); Node *current = dict->buckets[index]; while (current != NULL) if (strcmp(current->key, key) == 0) *output_value = current->value; return 1; // Found current = current->next; return 0; // Not Found // 5. Delete a key-value pair from the dictionary int delete(Dictionary *dict, const char *key) unsigned long index = hash_function(key); Node *current = dict->buckets[index]; Node *prev = NULL; while (current != NULL) if (strcmp(current->key, key) == 0) if (prev == NULL) // Node to delete is the first node in the bucket dict->buckets[index] = current->next; else // Node to delete is inside the chain prev->next = current->next; free(current->key); free(current); return 1; // Successfully deleted prev = current; current = current->next; return 0; // Key not found // 6. Free all allocated dictionary memory void free_dictionary(Dictionary *dict) for (int i = 0; i < TABLE_SIZE; i++) Node *current = dict->buckets[i]; while (current != NULL) Node *temp = current; current = current->next; free(temp->key); free(temp); free(dict); // Main function demonstrating usage int main() Dictionary *my_dict = create_dictionary(); // Insertion insert(my_dict, "apple", 45); insert(my_dict, "banana", 90); insert(my_dict, "orange", 120); // Updating an existing key insert(my_dict, "apple", 50); // Lookups int target_value; char *search_key = "apple"; if (lookup(my_dict, search_key, &target_value)) printf("Key '%s' found with value: %d\n", search_key, target_value); else printf("Key '%s' not found.\n", search_key); search_key = "grapes"; if (lookup(my_dict, search_key, &target_value)) printf("Key '%s' found with value: %d\n", search_key, target_value); else printf("Key '%s' not found.\n", search_key); // Deletion if (delete(my_dict, "banana")) printf("Successfully deleted 'banana'.\n"); else printf("Failed to delete 'banana'.\n"); // Verify deletion if (!lookup(my_dict, "banana", &target_value)) printf("Verified: 'banana' no longer exists in the dictionary.\n"); // Memory Cleanup free_dictionary(my_dict); return 0; Use code with caution. Detailed Code Breakdown The DJB2 String Hash

-------------------------------------------------------------*/ void dict_insert(Dict *d, const char *key, int value) unsigned int idx = hash(key, d->size); Node *curr = d->table[idx];

: Since different keys can hash to the same index, strategies like Separate Chaining (linked lists at each index) or Linear Probing (finding the next open slot) are required. Implementation in C (Separate Chaining) current = current->next