ccousas

estruturas de datos e algoritmos en C
Log | Files | Refs

commit b870f7276c79356b0cacce012f3d04f25ca7a406
parent cf1d09cb5650940d5d80fbfc37214b8fc6baab42
Author: x0tero <gxoelotero@gmail.com>
Date:   Tue,  5 Mar 2024 11:34:47 +0100

hashTable, hashMap ou diccionario en C

Diffstat:
AhashTable/hash_table.c | 199+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 199 insertions(+), 0 deletions(-)

diff --git a/hashTable/hash_table.c b/hashTable/hash_table.c @@ -0,0 +1,198 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define TABLE_SIZE 5 + +typedef struct ENTRY { + char* key; + char* value; + struct ENTRY* sig; +} ENTRY_T; + +typedef struct { + ENTRY_T** entries; +} HTABLE_T; + + + +HTABLE_T* htable_init() { + HTABLE_T* hashtable = malloc(sizeof(HTABLE_T)); // Allocate HashTable + hashtable->entries = calloc(TABLE_SIZE, sizeof(ENTRY_T)); // Allocate entries + + // Set each entry to NULL (needed for proper operation) + for (int i = 0; i < TABLE_SIZE; i++) { + hashtable->entries[i] = NULL; + } + + return hashtable; +} + + + +unsigned int hash(const char* key) { + unsigned long int value = 0; + + for (unsigned int i = 0; i < strlen(key); i++){ + value = value * 37 + key[i]; + } + value = value % TABLE_SIZE; + return value; +} + + + +// Inicializa un nodo entry +ENTRY_T* htable_pair(const char* key, const char* value){ + // Allocate the entry + ENTRY_T* entry = malloc(sizeof(entry)); + entry->key = malloc(strlen(key)+1); // +1 polo NULL TERMINATOR '\0' + entry->value = malloc(strlen(value) + 1); + + // Copy the key and value in place + strcpy(entry->key, key); + strcpy(entry->value, value); + + // sig (seguinte) starts out NULL but may be set later on + entry->sig = NULL; + return entry; +} + + +void htable_set (HTABLE_T* hashtable, const char* key, const char* value) { + unsigned int slot = hash(key); + ENTRY_T* entry = hashtable->entries[slot]; + + if (entry == NULL) { + hashtable->entries[slot] = htable_pair(key, value); + return; + } + + // Mira se estas intentando introducir unha clave que xa tes no hashTable para actualizala + ENTRY_T* prev; + while (entry != NULL) { + // Comproba + if (!strcmp(entry->key, key)) { + // Update value + free(entry->value); + entry->value = malloc(strlen(value) + 1); + strcpy(entry->value, value); + return; + } + + // walk to next + prev = entry; + entry = prev->sig; + } + + // End of node list reached -> add new element + prev->sig = htable_pair(key, value); +} + + +// Devolve NULL senon existe +char* htable_get(HTABLE_T* hashtable, const char* key) { + unsigned int slot = hash(key); + + // Try to find a valid slot + ENTRY_T* entry = hashtable->entries[slot]; + + // No slot means no entry + if (entry == NULL) return NULL; + + // Walk through each entry in the slot, which could just be a single thing + while (entry != NULL) { + // Return a value if found + if (!strcmp(entry->key, key) == 0) { + return entry->value; + } + + // Proceed to next key if available + entry = entry->sig; + } + + // Reaching here means there were >= 1 entries but no key match + return NULL; +} + + +void htable_remove(HTABLE_T* hashtable, const char* key) { + unsigned int slot = hash(key); + // Try to find a valid slot + ENTRY_T* entry = hashtable->entries[slot]; + ENTRY_T** tmp = &(hashtable->entries[slot]); + if (entry == NULL) return; + + // Se esta na cabeza e ten sig deixas o sig a cabeza + // Senon ten sig borraslle a cabeza + if (!strcmp(entry->key, key)) { + if (entry->sig == NULL) { + hashtable->entries[slot] = NULL; + free(entry); + } + else { + hashtable->entries[slot] = entry->sig; + free(entry); + } + } + else { + ENTRY_T* aux; + while (*tmp != NULL) { + if (!strcmp((*tmp)->key, key)) { + // Borrar a entry + aux = *tmp; + *tmp = (*tmp)->sig; + return; + } + tmp = &((*tmp)->sig); + } + } + return; +} + + +void htable_print(HTABLE_T* hashtable) { + for (int i = 0; i < TABLE_SIZE; i++) { + ENTRY_T* entry = hashtable->entries[i]; + + if (entry == NULL) continue; + + printf("slot[%4d]: ", i); + for(;;) { + printf("%s=%s ", entry->key, entry->value); + + if(entry->sig == NULL) break; + entry = entry->sig; + } + + printf("\n"); + } +} + + + +int main() { + HTABLE_T* ht = htable_init(); + + htable_set(ht, "name1", "em"); + htable_set(ht, "name2", "russian"); + htable_set(ht, "name3", "pizza"); + htable_set(ht, "name4", "doge"); + htable_set(ht, "name5", "pyro"); + htable_set(ht, "name6", "joost"); + htable_set(ht, "name7", "kalix"); + htable_set(ht, "name8", "lemon"); + htable_set(ht, "name9", "lollipop"); + htable_set(ht, "name10", "oreo"); + htable_set(ht, "name11", "apache"); + htable_set(ht, "name12", "fanta"); + htable_set(ht, "name13", "kake"); + htable_set(ht, "name14", "tuna"); + htable_set(ht, "name15", "presunto"); + + htable_remove(ht, "name7"); + htable_remove(ht, "name2"); + + htable_print(ht); + return 0; +} +\ No newline at end of file