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 的查表安装功能的主要内容,如果未能解决你的问题,请参考以下文章

使用C语言的查表和移位实现简单流水灯

使用C语言的查表和移位实现简单流水灯

使用C语言的查表和移位实现简单流水灯

利用OpenCV的函数LUT()对矩阵的数据进行查表映射

模板 线段树(部分功能)

单向链表的查删改功能,以及约瑟夫环,相交链表的第一个相交节点的查找等相关问题