散列表(三):衝突處理的方法之開地址法(線性探測再雜湊的實現)
阿新 • • 發佈:2019-02-11
printf("The hash table has free.\n");
}
void *hash_lookup_entry(hash_t *hash, void *key, unsigned int key_size)
{
hash_node_t *node = hash_get_node_by_key(hash, key, key_size);
if (node == NULL)
{
return NULL;
}
return node->value;
}
void hash_add_entry(hash_t *hash, void *key, unsigned int key_size,
void *value, unsigned int value_size)
{
if (hash_lookup_entry(hash, key, key_size))
{
fprintf(stderr, "duplicate hash key\n");
return;
}
unsigned int bucket = hash_get_bucket(hash, key);
unsigned int i = bucket;
// 找到的位置已經有人存活,向下探測
while (hash->nodes[i].status == ACTIVE)
{
i = (i + 1) % hash->buckets;
if (i == bucket)
{
// 沒找到,並且表滿
return;
}
}
hash->nodes[i].status = ACTIVE;
if (hash->nodes[i].key) //釋放原來被邏輯刪除的項的記憶體
{
free(hash->nodes[i].key);
}
hash->nodes[i].key = malloc(key_size);
memcpy(hash->nodes[i].key, key, key_size);
if (hash->nodes[i].value) //釋放原來被邏輯刪除的項的記憶體
{
free(hash->nodes[i].value);
}
hash->nodes[i].value = malloc(value_size);
memcpy(hash->nodes[i].value, value, value_size);
}
void hash_free_entry(hash_t *hash, void *key, unsigned int key_size)
{
hash_node_t *node = hash_get_node_by_key(hash, key, key_size);
if (node == NULL)
return;
// 邏輯刪除,置標誌位
node->status = DELETED;
}
unsigned int hash_get_bucket(hash_t *hash, void *key)
{
// 返回雜湊地址
unsigned int bucket = hash->hash_func(hash->buckets, key);
if (bucket >= hash->buckets)
{
fprintf(stderr, "bad bucket lookup\n");
exit(EXIT_FAILURE);
}
return bucket;
}
hash_node_t *hash_get_node_by_key(hash_t *hash, void *key, unsigned int key_size)
{
unsigned int bucket = hash_get_bucket(hash, key);
unsigned int i = bucket;
while (hash->nodes[i].status != EMPTY && memcmp(key, hash->nodes[i].key, key_size) != 0)
{
i = (i + 1) % hash->buckets;
if (i == bucket) // 探測了一圈
{
// 沒找到,並且表滿
return NULL;
}
}
// 比對正確,還得確認是否還存活
if (hash->nodes[i].status == ACTIVE)
{
return &(hash->nodes[i]);
}
// 如果執行到這裡,說明i為空位或已被刪除
return NULL;
}
}
void *hash_lookup_entry(hash_t *hash, void *key, unsigned int key_size)
{
hash_node_t *node = hash_get_node_by_key(hash, key, key_size);
if (node == NULL)
{
return NULL;
}
return node->value;
}
void hash_add_entry(hash_t *hash, void *key, unsigned
void *value, unsigned int value_size)
{
if (hash_lookup_entry(hash, key, key_size))
{
fprintf(stderr, "duplicate hash key\n");
return;
}
unsigned int bucket = hash_get_bucket(hash, key);
unsigned int i = bucket;
// 找到的位置已經有人存活,向下探測
{
i = (i + 1) % hash->buckets;
if (i == bucket)
{
// 沒找到,並且表滿
return;
}
}
hash->nodes[i].status = ACTIVE;
if (hash->nodes[i].key) //釋放原來被邏輯刪除的項的記憶體
{
free(hash->nodes[i].key);
}
hash->nodes[i].key = malloc(key_size);
memcpy(hash->nodes[i].key, key, key_size);
if
{
free(hash->nodes[i].value);
}
hash->nodes[i].value = malloc(value_size);
memcpy(hash->nodes[i].value, value, value_size);
}
void hash_free_entry(hash_t *hash, void *key, unsigned int key_size)
{
hash_node_t *node = hash_get_node_by_key(hash, key, key_size);
if (node == NULL)
return;
// 邏輯刪除,置標誌位
node->status = DELETED;
}
unsigned int hash_get_bucket(hash_t *hash, void *key)
{
// 返回雜湊地址
unsigned int bucket = hash->hash_func(hash->buckets, key);
if (bucket >= hash->buckets)
{
fprintf(stderr, "bad bucket lookup\n");
exit(EXIT_FAILURE);
}
return bucket;
}
hash_node_t *hash_get_node_by_key(hash_t *hash, void *key, unsigned int key_size)
{
unsigned int bucket = hash_get_bucket(hash, key);
unsigned int i = bucket;
while (hash->nodes[i].status != EMPTY && memcmp(key, hash->nodes[i].key, key_size) != 0)
{
i = (i + 1) % hash->buckets;
if (i == bucket) // 探測了一圈
{
// 沒找到,並且表滿
return NULL;
}
}
// 比對正確,還得確認是否還存活
if (hash->nodes[i].status == ACTIVE)
{
return &(hash->nodes[i]);
}
// 如果執行到這裡,說明i為空位或已被刪除
return NULL;
}