具有链表的哈希表

时间:2014-06-22 17:19:04

标签: c linked-list hashtable

我在上学时遇到了麻烦。

我必须使用这种结构实现哈希表:

struct Book {
char * title;
char * author;
int price;
struct Book * next;
}

所以我必须创建一个函数initTable()来创建我的哈希表,这是一个包含1000个元素的struct Book的表。所以我的功能是:

struct Book* initTable(){
struct Book *tab = malloc(sizeof(struct Book) * 1000);
return tab;
}

请注意,该函数应该返回表的第一个元素。 但我不知道这种语法是否正确。

所以我的问题是:

  1. 这是正确的语法吗?

  2. 如何在表格中导航?例如,如果我想去我桌子的单元格50,我该怎么办?

  3. 然后,如果我的哈希表中存在冲突,我必须创建一个链接列表,我将我的元素置于冲突中。但是我桌子的每个单元格都是一个结构而不是这个结构的指针,所以我不明白我如何链接我的元素。

2 个答案:

答案 0 :(得分:1)

哈希表用于在常量时间内按键查找集合中的条目。在实施方面,这通常包括"隐藏"对象指针数组(不是对象本身)。然后,您需要一个将键转换为数组查找索引(整数)的散列函数。举个例子:

ValueObjectType **createHashTable(int hashSize)
{
    ValueObjectType **table = malloc( sizeof(ValueObjectType *) * hashSize);
    return table;
}

void hashInsert(ValueObjectType **hashTable, KeyObjectType key, ValueObjectType *value)
{
    int arrayIndex = hashingFunction(key);
    if ( hashTable[arrayIndex] != NULL ) traverseLinkedListAndAdd(...);
    else hashTable[arrayIndex] = value;
}

ValueObjectType *lookupByKey(ValueObjectType **hashTable, KeyObjectType key)
{
    int arrayIndex = hashingFunction(key);
    return traverseLinkedListAndReturnObjectWithKey(...);        
}

散列函数通常涉及获取一个或多个关键元素(可以是任何类型)并将它们转换为单个整数值,然后通过获取散列数组大小的模数将其转换为数组索引。

Book结构中链表的目的是处理哈希冲突。插入时发生哈希冲突,因为哈希中已存在给定键(在这种情况下,您应该使用新对象替换值对象引用),或者因为哈希函数的非唯一性。当后者发生时,链表用于存储具有不同键的多个条目,这些键散列到相同的数组索引(通常通过迭代列表,如果看到键相等则替换列表的元素,否则添加新对象)在最后)。

在上面的示例代码中,我有一个单独的密钥对象,但是为了评估密钥的相等性,它需要包含在对象本身中(我怀疑在你的情况下密钥是标题和作者的某种组合) ,或包含在元结构中(例如" KeyValue"结构,其中包含指向键和值的指针,您将使用散列而不是ValueObjectType)。您需要提供逻辑来评估两个键的相等/不等式,以便正确处理哈希冲突情况。

我已经离开了散列函数,链接列表导航和未指定的密钥相等逻辑,因为这显然是教师希望您学习如何做的。

答案 1 :(得分:0)

你想要

malloc(sizeof(struct book) * 1000)

malloc所做的是分配内存。首先是对象开始的指针,然后是将存储在此对象中的任何其他内容的附加空间。在您的情况下,您想要创建一个包含1000个对象的数组,因此您需要在初始指针之后为所有这些对象分配内存。

用于导航已分配的数组,查看指针算术。这意味着你要在偏离初始指针的位置寻找一个对象。

开始指针算术检查http://www.eskimo.com/~scs/cclass/notes/sx10b.html