我试图使用线性探测来理解和实现哈希表。在搜索实现时,我遇到了一段搜索方法的代码:
struct DataItem *search(int key) {
//get the hash
int hashIndex = hashCode(key);
//move in array until an empty
while(hashArray[hashIndex] != NULL) {
if(hashArray[hashIndex]->key == key)
return hashArray[hashIndex];
//go to next cell
++hashIndex;
//wrap around the table
hashIndex %= SIZE;
}
return NULL;
}
我不明白的是,如果hashArray中的所有条目都已被一个键占用,那么while循环是否应该变为无限?或者这种情况从未发生过?有什么我想念的吗?
答案 0 :(得分:1)
正如您所说,如果所有单元格已满并且表中不存在key
,则此实现将陷入循环。以下是应该有效的实现:
struct DataItem *search(int key) {
//get the hash
int initialHashIndex = hashCode(key) % SIZE;
//move in array until an empty
int hashIndex = initialHashIndex;
while(hashArray[hashIndex] != NULL) {
if(hashArray[hashIndex]->key == key)
return hashArray[hashIndex];
//go to next cell
++hashIndex;
//wrap around the table
hashIndex %= SIZE;
//check if all the items are checked
if (hashIndex == initialHashIndex)
break;
}
return NULL;
}
但是,应该实施策略以避免让哈希表的占用率超过某个阈值。请记住,哈希表的主要目的是提供常量平均(摊销)操作时间,与哈希中存储的元素数量无关。因此,如果线性探测哈希值中的哈希表占用率很高,则搜索时间将是存储元素的函数,这会消除使用哈希的主要目标。
答案 1 :(得分:0)
实际上,如果hashArray
中的所有条目都被占用,那么这是一个无限循环。此代码假定hashArray
永远不会被完全占用。
使用探测的哈希表应该有一些最小比例的空闲时隙,否则它将回退到探测许多元素,并且探测的长度可能很长。因此,还有另一个原因可以确保数组永远不会被完全占用。
根据hashArray
和hashArray
的大小,代码可能会维护一个包含元素数量的字段。这样,如果占用的插槽的比例超过或低于某个分数,它可以调整hashArray
的大小。