k&r 的查表安装功能
Posted
技术标签:
【中文标题】k&r 的查表安装功能【英文标题】:Table lookup install function from k&r 【发布时间】:2011-10-24 07:02:20 【问题描述】: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;
当我试图理解这一点时,我不断得出这样的结论,即列表现在链接回自身,如果您尝试遍历链接列表,它将像狗追逐自己的尾巴一样。我希望代码将 np->next 设置为 NULL。
我不明白什么?这段代码是怎么工作的?
【问题讨论】:
【参考方案1】:这导致新值被插入到列表的开头。
所以它来自:
hashtab[hashval] --> original_list
到:
hashtab[hashval] --> original_list
np->next --> original_list
到:
hashtab[hashval] --> *np
np->next --> original_list
黄金法则是,如果链表代码没有意义,请务必画出图表!
【讨论】:
+1 我在关于指针的文章中也说过一些话。中肯的建议。【参考方案2】:hashtab[hashval] 是一个指针,而不是一个值。 它是指向内存中地址的指针,其中指针表中该特定行的第一个元素 (static struct nlist *hashtab[HASHSIZE]) 驻留。 np 和 np->next 也是指针。 所以这就是这两行中发生的事情: 第一行:将表中该行中第一个元素的指针复制到 np->next 中。 np->next 现在指向内存中该行的第一个元素曾经指向的地址。 第二行:指向新 *np 所在内存地址的指针现在被复制到指针中 变量 hastab[hashval]。 hastab[hashval] 现在再次成为指向该表行的第一个元素所在位置的指针。 因此,正如 Oli 所写,新的 *np 被插入到表中特定行的开头。
【讨论】:
【参考方案3】:那里已经有一个节点。该节点为空。通过将 nlist 结构定义为静态,它会自动将其所有元素指针初始化为 NULL。
如果我错了,请纠正我。
【讨论】:
【参考方案4】:但是这里没有原始列表。它是在插入一个没有找到键的节点,对吧?
if ((np = lookup(name)) == NULL) /* not found */
【讨论】:
以上是关于k&r 的查表安装功能的主要内容,如果未能解决你的问题,请参考以下文章