来自书籍K& C的C列表环R

时间:2016-04-13 02:53:02

标签: c

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;

我的问题是为什么他们不直接将它分配给next而不是插入它?即,

hashtab[hashval]->next = np; 
np->next = NULL;

进行插入技巧的好处是什么?

2 个答案:

答案 0 :(得分:2)

在链式哈希中,通常在前面添加新元素,这就是为什么np始终是哈希表中列表的头部。它有点使用缓存局部性,也就是说,最近访问的那个可能会被再次访问。

此外,您的更改无法正常工作,因为它只是将np添加到哈希列表的下一个元素,但是之后的所有元素都将丢失。

答案 1 :(得分:1)

原因是地点。

在代码中,在哈希数组列表的第一个列表中插入一个新节点。当hashtab [hashval]为null(在第一个时)时,您的建议会导致分段错误,除非您在if语句中检查此情况。代码在第一时添加而不用担心这种情况。