【发布时间】:2018-11-20 02:08:04
【问题描述】:
我在 C 中创建一个 HashTable,它使用 Node 双指针并使用单独的链接来解决冲突,但是当我运行我的代码时,它不会将冲突放入链表中。
HTable *createTable(size_t size, int (*hashFunction)(size_t tableSize,
int key),void (*destroyData)(void *data),void (*printData)(void
*toBePrinted)){
HTable * h = malloc(sizeof(HTable));
h->size = size;
h->destroyData = destroyData;
h->hashFunction = hashFunction;
h->printData = printData;
h->table = malloc(h->size * sizeof(Node*));
for(int i = 0; i < h->size; i++){
h->table[i] = malloc(sizeof(Node));
h->table[i]->key = 0;
h->table[i]->data = NULL;
h->table[i]->next = NULL;
}
return h;
}
Node *createNode(int key, void *data){
Node * n = malloc(sizeof(Node));
n->key = key;
n->data = data;
n->next = NULL;
return n;
}
void insertData(HTable *hashTable, int key, void *data){
if(hashTable != NULL){
Node * n = createNode(key, data);
int index = hashTable->hashFunction(hashTable->size, key);
if(hashTable->table[index] != NULL)
if(hashTable->table[index]->key == key){
if(hashTable->table[index]->next != NULL){
n->next = hashTable->table[index]->next;
hashTable->table[index] = n;
}
else
hashTable->table[index] = n;
}
else{
if(hashTable->table[index]->next != NULL){
Node * itr = hashTable->table[index];
while(itr->next != NULL){
itr = itr->next;
}
itr->next = n;
}
else
hashTable->table[index] = n;
}
else{
hashTable->table[index] = n;
}
}
}
HTable 敲击和 Node 敲击看起来像这样:
typedef struct Node
{
int key;
void *data;
struct Node *next;
} Node;
typedef struct HTable
{
size_t size;
Node **table;
void (*destroyData)(void *data);
int (*hashFunction)(size_t tableSize, int key);
void (*printData)(void *toBePrinted);
}HTable;
我认为当我使用迭代器查找链接列表中的最后一项时,我的 insertData 函数遇到了问题。那或者我误解了正确使用指向节点的双指针。
【问题讨论】:
-
对不起,这是在 C 中
-
当
if(hashTable->table[index]->key == key)为真时,你扔掉旧链,只把新节点放在那里,在我看来。 -
对于散列值使用无符号类型也是一个强烈的建议。您不希望在
hashTable->table[index]中出现负索引。 -
@ArndtJonasson 的想法是每个键只有一组数据,因此如果有 2 个匹配的键我替换数据,但如果 2 个不同的键导致同一个 bin,我将其添加到链条
-
是的,你替换那个节点,然后扔掉它的
next指向的东西。
标签: c hashmap hashtable linkedhashmap