Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中链表的链表_C_Linked List_Hashtable - Fatal编程技术网

C语言中链表的链表

C语言中链表的链表,c,linked-list,hashtable,C,Linked List,Hashtable,我有一个C语言的项目,我需要创建一个带有链表的链式哈希表。 实际上,我看到的是一个链表,链表是节点。 因此,哈希表中每个条目中每个节点的数据结构应为: typedef struct node { int value; int counter; struct node *next; } t_listnode; 然后,应包含上述节点的哈希表如下所述: typedef struct { t_listnode *head; t_listnode *tail; }

我有一个C语言的项目,我需要创建一个带有链表的链式哈希表。 实际上,我看到的是一个链表,链表是节点。 因此,哈希表中每个条目中每个节点的数据结构应为:

typedef struct node {
    int value;
    int counter;
    struct node *next;
} t_listnode;
然后,应包含上述节点的哈希表如下所述:

typedef struct {
    t_listnode *head;
    t_listnode *tail;
} t_htentry;
我已经耗尽了我的大脑(第一次接触链表),不知道如何创建哈希表以及如何在每个条目中输入数据。 任何帮助都将不胜感激


谢谢大家!

此答案假设您使用的是外部链表和内部链表:

首先,为了让您的生活更轻松,您应该为您的内部链表
节点制定一些方法:

  • insert()
    :迭代到链表的末尾并添加新节点
  • find()
    :遍历列表,查看您的值是否是您要查找的值
接下来,您将要实现哈希表的相关方法:

  • get()
    find()
    :对要查找的元素进行哈希运算,以获取外部链接列表中的索引,然后在该索引处遍历内部链接列表以查找要查找的元素
  • put()
    insert()
    :散列您要查找的元素以获取外部链接列表中的索引,您将在该索引处附加到内部链接列表的末尾
最重要的是,对于哈希表,您需要创建
hash()
函数。在这种情况下,由于数据看起来是一个
int
,因此哈希函数应该接受一个int,然后将该int哈希到外部链接列表中的给定位置

由于您使用链表来表示哈希表的外部结构,因此您肯定需要创建一个
at()
方法,该方法迭代外部链表(
t_>try
),并返回指向内部链表索引的指针(在您的示例中,是
t_listnode
节点)

示例

我们想将10201302添加到哈希表中

第一步是将
t\u shEntry*哈希表[PRIME\u NUMBER]
预先分配给一个PRIME大小——也就是说,我们从一个大小为5的数组开始(数组中的每个索引由
[]
表示)。
t\u listnode*head
已经在每个
t\u sthtry*
中,(每个
t\u sthtry*
()
表示,head节点用
*
表示,tail节点用
t
表示)

第二步是散列我们的第一个数据点-10

int idx = hash(10); //-> 2
第三步是在外部列表中找到
idx
(2)<代码>哈希表[idx]
将为我们提供一个固定时间的查找

第四步是现在将数据点为5的节点附加到该列表中

// append value to hashtable[idx] (where "next" points to TAIL)
insert(hashtable[idx], 5);

[(*)]  [(*)]  [(*)]  [(*)]  [(*)]
  |      |      |      |      |
  |      |      v      |      |
  |      |     (5)     |      |
  |      |      |      |      |
  v      v      v      v      v
 (t)    (t)    (t)    (t)    (t)
第五步,我们现在进入下一个数据点201。让我们假设201个散列到
idx=2
。(从这一点开始,我省略了为所有没有任何数据的索引绘制
[(t)]
,但请注意它们仍然存在。)

下一步,我们将移动到最后一个数据点302。让我们假设302个散列到
idx=0

 idx = hash(302); //-> 0
 t_listnode * spot = positionAt(hashtable, idx);
 insert(spot, 302);

 [(*)]  [(*)]  [(*)]  [(*)]  [(*)]
   |             |
   v             v
 (302)          (5)
   |             |
   v             v
  (t)           (2)
                 |
                 v
                (t)
在哪里,

hash
看起来像

insert
看起来像

void insert(t_htentry * bucket, int value) {
  // copy spot to a new t_listnode* and iterate until spot->next is NULL
  // (i.e., t_htentry* tmp = bucket; tmp = bucket->head->next)
  // create a new node with t_listnode->value set to value
  // set the current spot's next to the new node
  // set the new node's next to the TAIL node
}
bool find(hashtable, int value) {
  // hash "value" and go to hashtable[idx] as before
  // iterate through hashtable[idx]'s linked list as before using a copy
  // of that t_htentry*.
  // if the node that you're on has ->value == value, return true
  // else continue until you're at the end of the list, and return false
}
find
看起来像

void insert(t_htentry * bucket, int value) {
  // copy spot to a new t_listnode* and iterate until spot->next is NULL
  // (i.e., t_htentry* tmp = bucket; tmp = bucket->head->next)
  // create a new node with t_listnode->value set to value
  // set the current spot's next to the new node
  // set the new node's next to the TAIL node
}
bool find(hashtable, int value) {
  // hash "value" and go to hashtable[idx] as before
  // iterate through hashtable[idx]'s linked list as before using a copy
  // of that t_htentry*.
  // if the node that you're on has ->value == value, return true
  // else continue until you're at the end of the list, and return false
}

此实现的性能将按
find
insert
摊销O(1)。理解原因很重要。

此答案假设您使用的是外部链表和内部链表:

首先,为了让您的生活更轻松,您应该为您的内部链表
节点制定一些方法:

  • insert()
    :迭代到链表的末尾并添加新节点
  • find()
    :遍历列表,查看您的值是否是您要查找的值
接下来,您将要实现哈希表的相关方法:

  • get()
    find()
    :对要查找的元素进行哈希运算,以获取外部链接列表中的索引,然后在该索引处遍历内部链接列表以查找要查找的元素
  • put()
    insert()
    :散列您要查找的元素以获取外部链接列表中的索引,您将在该索引处附加到内部链接列表的末尾
最重要的是,对于哈希表,您需要创建
hash()
函数。在这种情况下,由于数据看起来是一个
int
,因此哈希函数应该接受一个int,然后将该int哈希到外部链接列表中的给定位置

由于您使用链表来表示哈希表的外部结构,因此您肯定需要创建一个
at()
方法,该方法迭代外部链表(
t_>try
),并返回指向内部链表索引的指针(在您的示例中,是
t_listnode
节点)

示例

我们想将10201302添加到哈希表中

第一步是将
t\u shEntry*哈希表[PRIME\u NUMBER]
预先分配给一个PRIME大小——也就是说,我们从一个大小为5的数组开始(数组中的每个索引由
[]
表示)。
t\u listnode*head
已经在每个
t\u sthtry*
中,(每个
t\u sthtry*
()
表示,head节点用
*
表示,tail节点用
t
表示)

第二步是散列我们的第一个数据点-10

int idx = hash(10); //-> 2
第三步是在外部列表中找到
idx
(2)<代码>哈希表[idx]
将为我们提供一个固定时间的查找

第四步是现在将数据点为5的节点附加到该列表中

// append value to hashtable[idx] (where "next" points to TAIL)
insert(hashtable[idx], 5);

[(*)]  [(*)]  [(*)]  [(*)]  [(*)]
  |      |      |      |      |
  |      |      v      |      |
  |      |     (5)     |      |
  |      |      |      |      |
  v      v      v      v      v
 (t)    (t)    (t)    (t)    (t)
第五步,我们现在进入下一个数据点201。让我们