K&RC 编程语言书籍中哈希表的有效性

发布于 2025-01-15 08:38:15 字数 1707 浏览 0 评论 0原文

当我在 C 语言中搜索字典示例时,我遇到了 here stackoverflow 中的示例,其中引用了 K&R C 编程语言一书。在那本书中,第 6.6 节中有一个表查找主题。本节将表查找示例为哈希表。

在示例中,哈希表由 101 个大小的 nlist(以下代码片段中的结构)自引用节点组成。

我的问题是为什么他们使用自引用结构作为查找表?查找表作为键值对工作,因此我们不必保存下一个节点。

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

与该示例相关的问题的第二部分是针对 lookup(char *s) 函数中的循环语句。该循环仅工作一次,并且 np = np->next 表达式可能不相关,我认为或者可能有我错过的任何内容!

struct nlist *lookup(char *s)
{
    struct nlist *np;
    for (np = hashtab[hash(s)]; np != NULL; np = np->next)
        if (strcmp(s, np->name) == 0)
          return np; /* found */
    return NULL; /* not found */
}

我问题的最后一部分是关于函数 *install(char *name, char *defn) 中的赋值 np->next = hashtab[hashval]; (下面的函数),实际上它将当前节点分配给自己作为下一个节点。

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;
}

提前致谢。

As I am searching dictionary example in C, I have come accross the example in here stackoverflow which references K&R The C Programming Language book. In that book, there is a table lookup topic in section 6.6. The section exemplifies table lookup as a hash table.

The hashtable is formed by 101 sized nlist(the struct in the below code snippet) self-referential nodes in the example.

My question is here why they have used self-referential struct for a lookup table? Look-up tables work as key-value pair so we dont have to hold next node.

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

The second part of my question related with the example is for the loop statement in the lookup(char *s) function. The loop works only for one time and also np = np->next expression may irrelevant, i think or there could be anything that i missed!

struct nlist *lookup(char *s)
{
    struct nlist *np;
    for (np = hashtab[hash(s)]; np != NULL; np = np->next)
        if (strcmp(s, np->name) == 0)
          return np; /* found */
    return NULL; /* not found */
}

The last part of my question is about the assignment np->next = hashtab[hashval]; (the function below) in the function *install(char *name, char *defn), actually it assignes its current node to itself as a next node.

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;
}

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

顾忌 2025-01-22 08:38:15

该表不是直接使用键进行索引,而是使用键的散列进行索引。不同的密钥可能具有相同的哈希值。这称为哈希冲突

  1. 此实现将与具有相同哈希的键相对应的所有值存储为链表,因此是一个自引用结构。该表存储键值对的链表。同一列表中的所有键都具有相同的哈希值。 (这不是处理碰撞的唯一方法)。
  2. 如果发生碰撞,循环会多次工作。如果您没有看到此循环执行多次,请继续添加条目,直到发生碰撞。
  3. 不,它不会为自己分配节点。它将新分配的节点插入链表的头部。列表的前一个头成为列表中的第二个节点。

The table is not indexed with keys directly, but with hashes of keys. Different keys may have the same hash. This is called hash collisions.

  1. This implementation stores all values that correspond to keys with the same hash as a linked list, thus a self referential structure. The table stores linked lists of key-value pairs. All keys in the same list have the same hash. (This is not the only method of handling collisions).
  2. In case of a collision, the loop does work more than once. It you don't see this loop executing more than once, keep adding entries until you hit a collision.
  3. No, it does not assign a node to itself. It inserts a newly allocated node at the head of the linked list. The former head of the list becomes the second node in the list.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文