【发布时间】:2016-08-03 22:01:18
【问题描述】:
K&R 的第 6.6 节讨论了使用链表的哈希表。
简而言之,哈希表是一个指针数组。指针指向一个链表。链表是一个结构,如下所示:
struct nlist { /* table entry: */
struct nlist *next; /* next entry in chain */
char *name; /* defined name */
char *defn; /* replacement text */
};
名称是经过散列的,这个散列决定了表中的索引。然后本章显示了将名称/定义对添加到表中的代码:
struct nlist *install(char *name, char *defn) {
struct nlist *np;
unsigned hashval;
if ((np = lookup(name)) == NULL) { /* not found */
np = (struct nlist *) malloc(sizeof(*np));
if (np == NULL || (np->name = strdup(name)) == NULL)
return NULL;
hashval = hash(name);
np->next = hashtab[hashval];
hashtab[hashval] = np;
} else /* already there */
free((void *) np->defn); /*free previous defn */
if ((np->defn = strdup(defn)) == NULL)
return NULL;
return np;
}
除了以下两行之外,一切都有意义:
np->next = hashtab[hashval];
hashtab[hashval] = np;
我的问题是他们为什么不直接将其分配给next 而不是插入它?即,
hashtab[hashval]->next = np;
np->next = NULL;
使用插入技巧有什么好处?
【问题讨论】:
-
要找到链表的末尾,必须遍历
next指针,直到找到最后一个节点。 -
hashtab[hashval]是第hashval链表的头指针,所以hashtab[hashval]->next = np这样的代码会失去头指针,除非你在编码之前做了一些迭代。 -
不要将
malloc和朋友或void *的结果转换为/从C 中的指针转换!并使用至少涵盖 C99 的书 - 更好的标准 C。
标签: c