我在上学时遇到了麻烦。
我必须使用这种结构实现哈希表:
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;
}
请注意,该函数应该返回表的第一个元素。 但我不知道这种语法是否正确。
所以我的问题是:
这是正确的语法吗?
如何在表格中导航?例如,如果我想去我桌子的单元格50,我该怎么办?
然后,如果我的哈希表中存在冲突,我必须创建一个链接列表,我将我的元素置于冲突中。但是我桌子的每个单元格都是一个结构而不是这个结构的指针,所以我不明白我如何链接我的元素。
答案 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个对象的数组,因此您需要在初始指针之后为所有这些对象分配内存。
用于导航已分配的数组,查看指针算术。这意味着你要在偏离初始指针的位置寻找一个对象。