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:
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