考虑以下代码段:
#include<stdio.h>
#include<conio.h>
#define TABLESIZE 100
sturct record{
int k;
int r;
}table[TABLESIZE];
int tcount=0;
int search_and_insert(int key,int rec){
int i;
i=h(key);
while(table[i].k!=key && table[i].k!=NULL)
i=rh(i);
if(table[i].key==NULL){
table[i].k=key;
table[i].r=rec;
tcount++;
}
return i;
}
int h(int key){
return key%1000;
}
int rh(int hkey){
int k;
if(hkey==99)
return 0;
return ((hkey+1)%1000);
}
while
循环可能是一个无限循环,如果表已满,为了解决这个问题,我可以
引入这样的if
语句:
if(tcount<TABLESIZE){
while(table[i].k!=key && table[i].k!=NULL)
i=rh(i);/*Rehash*/
if(table[i].key==NULL){
table[i].k=key;
table[i].r=rec;
tcount++;
}
}
但是根据我的说法,这会产生另一个问题,即当表格已满或搜索结果错误时,我将无法搜索表格中已存在的记录。
可以解决这个问题吗?
答案 0 :(得分:0)
这类问题的典型解决方案是链接,即让您的哈希键指向链接结构:
struct h_value
{
int rec;
struct h_value *next;
};
插入时,如果您查找位置并且rec不是您要插入的内容,则查看rec的所有下一个指针,如果您未在列表中找到它,请创建一个新的h_value并将其添加到结束。在最坏的情况下,您将拥有单链表,但在典型情况下,您将在所有存储桶中均匀分配您的值。
如果您提前知道自己的价值观,可能需要查看完美的哈希值,例如gperf。
答案 1 :(得分:0)
由于您正在进行简单的线性探测,因此您可以通过将当前哈希值与原始哈希值进行比较,轻松检查是否围绕哈希表进行了完整的循环。
int h0 = hash(key);
int h = h0;
do {
if (found_in_bucket(key, h))
return value_in_bucket(h);
h = rehash(h);
} while (h != h0);