来自k& r的表查找安装功能

时间:2011-08-10 17:00:01

标签: c hashtable

K& R的6.6节讨论了使用链表的哈希表。

简而言之,哈希表是一个指针数组。指针指向链表。链表是一个结构,如下所示:

struct nlist {             /* table entry: */
    struct nlist *next;    /* next entry in chain */
    char *name;            /* defined name */
    char *defn;            /* replacement text */
};

名称经过哈希处理,此哈希值确定表中的索引。然后,本章将显示将名称/ defn对添加到表中的代码:

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->设置为NULL。

我不理解什么?为什么这段代码有效?

4 个答案:

答案 0 :(得分:14)

导致新值插入列表的开头。

所以它来自:

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插入到表格中特定行的开头。

答案 2 :(得分:0)

但这里没有原始列表。它正在插入一个没有找到密钥的节点,对吗?

if ((np = lookup(name)) == NULL) { /* not found */ 

答案 3 :(得分:0)

那里已有一个节点。该节点为null。通过将nlist结构定义为静态,它会自动将其所有元素指针启动为NULL。

如果我错了,请纠正我。