/* * Tabulka s rozptýlenými položkami * * S využitím datových typů ze souboru hashtable.h a připravených koster * funkcí implementujte tabulku s rozptýlenými položkami s explicitně * zretězenými synonymy. * * Při implementaci uvažujte velikost tabulky HT_SIZE. */ #include "hashtable.h" #include #include int HT_SIZE = MAX_HT_SIZE; /* * Rozptylovací funkce která přidělí zadanému klíči index z intervalu * <0,HT_SIZE-1>. Ideální rozptylovací funkce by měla rozprostírat klíče * rovnoměrně po všech indexech. Zamyslete sa nad kvalitou zvolené funkce. */ int get_hash(char *key) { int result = 1; int length = strlen(key); for (int i = 0; i < length; i++) { result += key[i]; } return (result % HT_SIZE); } /* * Inicializace tabulky — zavolá sa před prvním použitím tabulky. */ void ht_init(ht_table_t *table) { // Inicializujeme všetky položky na NULL for (int i = 0; i < HT_SIZE; i++) { (*table)[i] = NULL; } } /* * Vyhledání prvku v tabulce. * * V případě úspěchu vrací ukazatel na nalezený prvek; v opačném případě vrací * hodnotu NULL. */ ht_item_t *ht_search(ht_table_t *table, char *key) { // Získame index pomocou hash funkcie int index = get_hash(key); // Prechádzame zoznam synoným ht_item_t *item = (*table)[index]; while (item != NULL) { // Ak nájdeme kľúč, vrátime položku if (strcmp(item->key, key) == 0) { return item; } item = item->next; } // Prvok nebol nájdený return NULL; } /* * Vložení nového prvku do tabulky. * * Pokud prvek s daným klíčem už v tabulce existuje, nahraďte jeho hodnotu. * * Při implementaci využijte funkci ht_search. Pri vkládání prvku do seznamu * synonym zvolte nejefektivnější možnost a vložte prvek na začátek seznamu. */ void ht_insert(ht_table_t *table, char *key, float value) { // Skúsime nájsť existujúci prvok ht_item_t *item = ht_search(table, key); if (item != NULL) { // Ak existuje, aktualizujeme hodnotu item->value = value; } else { // Vytvoríme nový prvok int index = get_hash(key); item = malloc(sizeof(ht_item_t)); if (item == NULL) { return; // Chyba alokácie } // Alokujeme a skopírujeme kľúč item->key = malloc(strlen(key) + 1); if (item->key == NULL) { free(item); return; } strcpy(item->key, key); // Nastavíme hodnotu a zaradíme na začiatok zoznamu synoným item->value = value; item->next = (*table)[index]; (*table)[index] = item; } } /* * Získání hodnoty z tabulky. * * V případě úspěchu vrací funkce ukazatel na hodnotu prvku, v opačném * případě hodnotu NULL. * * Při implementaci využijte funkci ht_search. */ float *ht_get(ht_table_t *table, char *key) { // Vyhľadáme prvok ht_item_t *item = ht_search(table, key); if (item != NULL) { // Ak existuje, vrátime pointer na hodnotu return &(item->value); } return NULL; } /* * Smazání prvku z tabulky. * * Funkce korektně uvolní všechny alokované zdroje přiřazené k danému prvku. * Pokud prvek neexistuje, funkce nedělá nic. * * Při implementaci NEPOUŽÍVEJTE funkci ht_search. */ void ht_delete(ht_table_t *table, char *key) { int index = get_hash(key); ht_item_t *item = (*table)[index]; ht_item_t *prev = NULL; // Prechádzame zoznam a hľadáme prvok while (item != NULL) { if (strcmp(item->key, key) == 0) { // Našli sme prvok na zmazanie if (prev == NULL) { // Je to prvý prvok v zozname (*table)[index] = item->next; } else { // Je to prvok v strede/na konci zoznamu prev->next = item->next; } // Uvoľníme pamäť free(item->key); free(item); return; } prev = item; item = item->next; } } /* * Smazání všech prvků z tabulky. * * Funkce korektně uvolní všechny alokované zdroje a uvede tabulku do stavu po * inicializaci. */ void ht_delete_all(ht_table_t *table) { // Prechádzame všetky položky tabuľky for (int i = 0; i < HT_SIZE; i++) { ht_item_t *item = (*table)[i]; // Postupne mažeme všetky prvky v zozname synoným while (item != NULL) { ht_item_t *next = item->next; free(item->key); free(item); item = next; } // Inicializujeme položku na NULL (*table)[i] = NULL; } }