【问题标题】:C - Trying to make an array of LinkedList pointersC - 试图创建一个 LinkedList 指针数组
【发布时间】:2018-04-24 23:16:21
【问题描述】:

我正在尝试在 C 中创建一个 HashTable,其中每个“桶”都是指向 LinkedList 的指针。也就是说,我需要创建一个LinkedList 指针数组。

截至目前,SomeHashTable->Buckets[i] 正在返回一个非指针 LinkedList。我一直在到处寻找答案,但我什么也找不到。也许我忽略了什么?我在下面给出了我当前的代码。

HashTable.h

#include "LinkedList.h"

typedef struct HashTable
{
  LinkedList* Buckets[1009];
} HashTable;

//Creates new hashtable
HashTable* HashTable_new();

//Hashes and adds a new entry
void HashTable_add(HashTable* Table, int data);

HashTable.c

#include "HashTable.h"
HashTable* HashTable_new()
{
  HashTable* newTable = (HashTable*)malloc(sizeof(HashTable));
  newTable->Buckets = malloc(1009 * sizeof(LinkedList*));

  //Create linked lists
  for (int i = 0; i < 1009; i++)
  {
    newTable->Buckets[i] = LinkedList_new();
  }

  return newTable;
}

void HashTable_add(HashTable* Table, int data)
{
  int index = data % 1009;

  //Get bucket to hash to
  LinkedList* BucketHead = (Table->Buckets[index]);
  //Hash it iiinnnn real good
  LinkedList_add_at_end(BucketHead, data);
}

链表结构供参考:

typedef struct LinkedListNode {
    int data;
    struct LinkedListNode *next;
    struct LinkedListNode *prev;
} LinkedListNode;

typedef struct LinkedList {
    struct LinkedListNode *first;
    struct LinkedListNode *last;
} LinkedList;

【问题讨论】:

  • 为什么要分配内存给Buckets --> newTable-&gt;Buckets = malloc(1009 * sizeof(LinkedList*));Buckets 已经是 1009 类型为 LinkedList* 的元素的数组。
  • 一本好书Eternally Confuzzled - Hash Tables。非常值得一读。另一个来自耶鲁大学的C/HashTables 都很有帮助。收藏Coding a Hash Table
  • 另外,除非你有一些无法解释的目的来使用桶的 双向链表,否则它通常是单向街道(例如 单向链表) 实现)在初始填充或重新散列以保持 负载因子 低于目标(通常.7 可以)时,您不会受益于双重链接

标签: c arrays pointers linked-list hashtable


【解决方案1】:

正如 H.S. 的评论所提到的,没有必要动态地——并且——静态地分配 Buckets 数组。

这一行:

newTable->Buckets = malloc(1009 * sizeof(LinkedList*));

正在覆盖指向静态分配数组的指针,这可能不是您想要的。为了可扩展性,我会放弃静态数组并坚持使用 malloc()。这样,您可以使用 HashTable_new() 的参数来指定存储桶数组的大小,如下所示:

HashTable* HashTable_new(int nBuckets)
{
  HashTable* newTable = (HashTable*)malloc(sizeof(HashTable));
  newTable->Buckets = malloc(nBuckets * sizeof(LinkedList*)); 
  newTable->nBuckets = nBuckets;

  //Create linked lists
  for (int i = 0; i < nBuckets; i++)
  {
    newTable->Buckets[i] = LinkedList_new();
  }

  return newTable;
}

请注意,newTable->Buckets 被分配为指向 LinkedList (LinkedList**) 的指针。您需要跟踪 Buckets[] 的大小,因此将变量添加到结构中,如下所示:

typedef struct HashTable
{
  int nBuckets;
  LinkedList **Buckets;
} HashTable;

只要 LinkedList_new() 的返回类型是 LinkedList* 就可以了,完成后别忘了将其全部释放。

【讨论】:

  • 谢谢!似乎现在可以工作了。我想知道为什么你 malloc'd nBuckets * LL** 与 LL* 并列。桶不应该只是指向链表的指针吗?不是双指针?
  • 你完全正确。我已经编辑了答案以反映这一点。请注意,由于 malloc() 返回 void* 并且指针通常与双指针大小相同,因此在功能上没有区别,因此无论哪种方式都可以。
猜你喜欢
  • 2012-08-02
  • 2018-03-12
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
  • 2021-10-17
  • 2017-04-12
相关资源
最近更新 更多