hash_table.c (4834B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #define TABLE_SIZE 5 6 7 typedef struct ENTRY { 8 char* key; 9 char* value; 10 struct ENTRY* sig; 11 } ENTRY_T; 12 13 typedef struct { 14 ENTRY_T** entries; 15 } HTABLE_T; 16 17 18 19 HTABLE_T* htable_init() { 20 HTABLE_T* hashtable = malloc(sizeof(HTABLE_T)); // Allocate HashTable 21 hashtable->entries = calloc(TABLE_SIZE, sizeof(ENTRY_T)); // Allocate entries 22 23 // Set each entry to NULL (needed for proper operation) 24 for (int i = 0; i < TABLE_SIZE; i++) { 25 hashtable->entries[i] = NULL; 26 } 27 28 return hashtable; 29 } 30 31 32 33 unsigned int hash(const char* key) { 34 unsigned long int value = 0; 35 36 for (unsigned int i = 0; i < strlen(key); i++){ 37 value = value * 37 + key[i]; 38 } 39 value = value % TABLE_SIZE; 40 return value; 41 } 42 43 44 45 // Inicializa un nodo entry 46 ENTRY_T* htable_pair(const char* key, const char* value){ 47 // Allocate the entry 48 ENTRY_T* entry = malloc(sizeof(entry)); 49 entry->key = malloc(strlen(key)+1); // +1 polo NULL TERMINATOR '\0' 50 entry->value = malloc(strlen(value) + 1); 51 52 // Copy the key and value in place 53 strcpy(entry->key, key); 54 strcpy(entry->value, value); 55 56 // sig (seguinte) starts out NULL but may be set later on 57 entry->sig = NULL; 58 return entry; 59 } 60 61 62 void htable_set (HTABLE_T* hashtable, const char* key, const char* value) { 63 unsigned int slot = hash(key); 64 ENTRY_T* entry = hashtable->entries[slot]; 65 66 if (entry == NULL) { 67 hashtable->entries[slot] = htable_pair(key, value); 68 return; 69 } 70 71 // Mira se estas intentando introducir unha clave que xa tes no hashTable para actualizala 72 ENTRY_T* prev; 73 while (entry != NULL) { 74 // Comproba 75 if (!strcmp(entry->key, key)) { 76 // Update value 77 free(entry->value); 78 entry->value = malloc(strlen(value) + 1); 79 strcpy(entry->value, value); 80 return; 81 } 82 83 // walk to next 84 prev = entry; 85 entry = prev->sig; 86 } 87 88 // End of node list reached -> add new element 89 prev->sig = htable_pair(key, value); 90 } 91 92 93 // Devolve NULL senon existe 94 char* htable_get(HTABLE_T* hashtable, const char* key) { 95 unsigned int slot = hash(key); 96 97 // Try to find a valid slot 98 ENTRY_T* entry = hashtable->entries[slot]; 99 100 // No slot means no entry 101 if (entry == NULL) return NULL; 102 103 // Walk through each entry in the slot, which could just be a single thing 104 while (entry != NULL) { 105 // Return a value if found 106 if (!strcmp(entry->key, key) == 0) { 107 return entry->value; 108 } 109 110 // Proceed to next key if available 111 entry = entry->sig; 112 } 113 114 // Reaching here means there were >= 1 entries but no key match 115 return NULL; 116 } 117 118 119 void htable_remove(HTABLE_T* hashtable, const char* key) { 120 unsigned int slot = hash(key); 121 // Try to find a valid slot 122 ENTRY_T* entry = hashtable->entries[slot]; 123 ENTRY_T** tmp = &(hashtable->entries[slot]); 124 if (entry == NULL) return; 125 126 // Se esta na cabeza e ten sig deixas o sig a cabeza 127 // Senon ten sig borraslle a cabeza 128 if (!strcmp(entry->key, key)) { 129 if (entry->sig == NULL) { 130 hashtable->entries[slot] = NULL; 131 free(entry); 132 } 133 else { 134 hashtable->entries[slot] = entry->sig; 135 free(entry); 136 } 137 } 138 else { 139 ENTRY_T* aux; 140 while (*tmp != NULL) { 141 if (!strcmp((*tmp)->key, key)) { 142 // Borrar a entry 143 aux = *tmp; 144 *tmp = (*tmp)->sig; 145 return; 146 } 147 tmp = &((*tmp)->sig); 148 } 149 } 150 return; 151 } 152 153 154 void htable_print(HTABLE_T* hashtable) { 155 for (int i = 0; i < TABLE_SIZE; i++) { 156 ENTRY_T* entry = hashtable->entries[i]; 157 158 if (entry == NULL) continue; 159 160 printf("slot[%4d]: ", i); 161 for(;;) { 162 printf("%s=%s ", entry->key, entry->value); 163 164 if(entry->sig == NULL) break; 165 entry = entry->sig; 166 } 167 168 printf("\n"); 169 } 170 } 171 172 173 174 int main() { 175 HTABLE_T* ht = htable_init(); 176 177 htable_set(ht, "name1", "em"); 178 htable_set(ht, "name2", "russian"); 179 htable_set(ht, "name3", "pizza"); 180 htable_set(ht, "name4", "doge"); 181 htable_set(ht, "name5", "pyro"); 182 htable_set(ht, "name6", "joost"); 183 htable_set(ht, "name7", "kalix"); 184 htable_set(ht, "name8", "lemon"); 185 htable_set(ht, "name9", "lollipop"); 186 htable_set(ht, "name10", "oreo"); 187 htable_set(ht, "name11", "apache"); 188 htable_set(ht, "name12", "fanta"); 189 htable_set(ht, "name13", "kake"); 190 htable_set(ht, "name14", "tuna"); 191 htable_set(ht, "name15", "presunto"); 192 193 htable_remove(ht, "name7"); 194 htable_remove(ht, "name2"); 195 196 htable_print(ht); 197 return 0; 198 }