在C中实现标签(使用链接列表以避免发生冲突的)的必要结构



嘿,我一直在阅读有关C的指针,结构和数据结构,过去几天。现在,我尝试通过沿本教程来实现C中的哈希表:https://www.tutorialspoint.com/data_sustructures_algorithms/hash_table_program_in_c.htm

但是,tutorialSpoint假设只有1个哈希表,并且它使其成为全局。此外,TutorialSpoint不考虑碰撞。

我想制作一个结构,不要将自己限制在单个哈希表上,我计划将链接(处理碰撞)与链接列表结合在一起。我有以下内容:

typedef struct node {
    int key;
    int data;
    struct node* next;
} node;
typedef struct linkedList{
    node* head;
    node* tail;
    size_t size;
} linkedList;
typedef struct hashTable{
    //perhaps an array of linked list? This member is what I need help with
    //And other potential members I am overlooking
    size_t size
} hashTable;

我需要解释的一些事情:

  1. 节点struct用作一对密钥/数据,它具有指向具有相同哈希代码的下一个对的指针。所有具有相同哈希代码的节点都将在同一链接列表中。

  2. linkedlist struct代表一个链接列表,最终将成为哈希表中的一行。所有链接列表将是哈希表中的一行。

  3. Hashtable结构包含所有链接清单。

我如何在我的Hashtable结构中制作链接列表结构的数组?我在三个结构中还有其他成员吗?

任何帮助都将受到赞赏!

P.S。我计划使用我在链接列表程序中写的方法。这是它的早期版本的链接:https://codereview.stackexchange.com/questions/176904/my-linked-list-implementation-in-in-c

typedef struct linkedList{
    node* head;
    node* tail;
    size_t size;
} linkedList;

我认为您在这里真的不需要size_t size。实际的哈希表结构,您可以做什么:

typedef struct has_map {
    linkedList** table; // stores the actual collision chains.
    size_t table_capacity; // the current capacity of table.
    size_t size; // number of mappings in this hash map.
} hash_map;

另外,我建议您将table的长度保持在两个:2、4、8、16,...这样您可以使用位操作hash_code & (hash_map->table_capacity - 1)

更改hash_code % hash_map->table_capacity

您可以使用节点和列表结构。然后,哈希表将只是一个带有一系列列表的结构。哈希表的大小可能是动态的,但让我们使用一个恒定的大小:

enum {
    hashSize = 32
};
typedef struct hashTable {
    linkedList list[hashSize];
    size_t size;                     // How many elelents overall?
} hashTable;

您的哈希函数必须返回一个无符号哈希值小于 hashSize

但是您实际上不需要链接的列表结构。该结构可以在前面和末端轻松插入,并且还可以保持其元素的数量。列表的元素未排序,因此您可以随时在正面插入,并且您实际上不需要大小,因此您只需通过指示来定义链接列表,最初是所有NULL

typedef struct hashTable {
    node *head[hashSize];
    size_t size;
} hashTable;

(但是,如果您已经有链接列表的代码,则可能是链接列表的数组。)


您链接的教程码头代码上的注释:它确实可以满足碰撞,但它使用了另一种方法:每个哈希代码只有一个插槽。如果已经使用了哈希代码的插槽,则使用下一个免费的哈希代码。

该方法意味着您不能简单地删除元素。想象一下,您插入了带有哈希值5的项目,但是该插槽已经由另一个带有不同键但相同哈希代码的项目插入。也要采用6和7,因此您将项目插入插槽8。如果搜索该项目,则首先搜索搜索插槽5,但是那里的项目不匹配。HES代码增加了,最终,该项目在插槽8中找到。如果我们首先找到一个空的插槽,则搜索将不会成功。在插槽5中删除该项目使插槽8中的项目无法访问。因此,必须将假人元素放入该插槽中。您的链接列表方法不需要这样的虚拟元素。

(TutorialSpoint方法还意味着,如果Hash表已满,您将搜索所有元素,这并不比搜索未分类数组更好。链接的列表哈希表将永远不会满足,但是当表中的项目远大于哈希表尺寸,性能会降低。)

最新更新