将第一个节点添加到hashmap中的链表时,为啥必须将新节点直接分配给索引指针?
Posted
技术标签:
【中文标题】将第一个节点添加到hashmap中的链表时,为啥必须将新节点直接分配给索引指针?【英文标题】:When adding first node to linked list in hashmap, why must the new node be assigned directly to the indexed pointer?将第一个节点添加到hashmap中的链表时,为什么必须将新节点直接分配给索引指针? 【发布时间】:2020-01-31 02:16:23 【问题描述】:这是我在 c 中实现的 hashmap 及其初始化和插入代码。 在 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 确实起作用时,我稍后在函数中也会感到困惑。 last 是一个指针,就像 head 一样,但它在那里工作。
感谢您的澄清。
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;
【问题讨论】:
【参考方案1】:'head' 指向一个 hashnode_t,'hm->table[i]' 也是如此。因此,它们都指向同一个对象。改变“头”只会使“头”指向其他地方。您实际上并未将 hashmap_t 中的指针分配给“new_node”。
'last' 起作用的原因是您将成员变量更改为新值。并且,由于“last”指向已经在 hashmap_t 中的对象,因此分配更新了 hastmap_t 中指向的对象。因此,对 'last->next = new_node' 的更新与 'hm->table[x]->next = new_node' 相同('x' 是一些任意索引)。
【讨论】:
哦,好吧,这很有意义!有没有办法在不直接执行 hm->table[i] = new_node 的情况下将 hashmap 中的指针分配给新节点?或者那是不可能的。我只是喜欢 head = new_node 看起来多么干净。 这是可能的,但是您需要使用指针地址重构代码,添加令人困惑的解引用并添加额外的错误检查。它会使代码更难阅读。以上是关于将第一个节点添加到hashmap中的链表时,为啥必须将新节点直接分配给索引指针?的主要内容,如果未能解决你的问题,请参考以下文章