Вот моя реализация hashmap в c, его инициализация и вставка кода. В структуре hashmap_t я использую массив указателей (таблица) на узлы, которые содержат пары ключ / значение. В hashmap_init я выделяю нужное количество узлов и перебираю массив, устанавливая каждый указатель в NULL.
Что меня смущает, так это функция hashmap_put. Я нахожу индекс, в список которого должен быть вставлен ключ, и на этот первый указатель ссылается hm-> table [i]. Для ясности я хочу убедиться, что очевидно, что hm-> table [i] является началом списка, поэтому я назначаю его hashnode_t * head.
Так что при вставке первого узла (head == NULL), Я изначально использовал head = new_node, но ни одна из моих вставок не работала. Это работает, только когда я использую hm-> table [i] = new_node.
Я не понимаю, почему это так. head указывает на то же самое, так почему установка head, равная new_node, не работает? Я также запутался позже в функции, когда last-> next = new_node работает. Последний указатель, как голова, но он работает там.
Спасибо за любые разъяснения.
typedef struct hashnode {
char key[128];
char val[128];
struct hashnode *next;
} hashnode_t;
typedef struct {
int item_count;
int table_size;
hashnode_t **table;
} hashmap_t;
void hashmap_init(hashmap_t *hm, int table_size) {
hm->table_size = table_size;
hm->item_count = 0;
hm->table = malloc(table_size * sizeof(hashnode_t));
for (int i = 0; i < table_size; i++) { // loop through array of pointers to nodes
hm->table[i] = NULL;
}
}
int hashmap_put(hashmap_t *hm, char key[], char val[]) {
hashnode_t *new_node = malloc(sizeof(hashnode_t)); // allocate new node
strcpy(new_node->key, key);
strcpy(new_node->val, val);
new_node->next = NULL;
int i = hashcode(key) % hm->table_size; // index of list hashed to
hashnode_t *head = hm->table[i];
hashnode_t *cur = head;
hashnode_t *last;
if (!head) { // list is empty
new_node->next = head;
hm->table[i] = new_node;
//why does head = new_node not work?
hm->item_count += 1;
return 1;
}
while (cur) { // loop through nodes
if (strcmp(cur->key, key) == 0) {
strcpy(cur->val, val);
free(new_node);
return 0;
}
last = cur; // save pointer to node that points to NULL
cur = cur->next;
}
last->next = new_node;
//why does it work here?
hm->item_count += 1;
return 1;
}