开放地址散列表(open addressing hashing):是一种不使用链表解决冲突的方法。如果有冲突发生,那么就要尝试选择另外的单元,直到找出空的单元为止。
1.线性探测法
2.平方探测法
3.双散列
//开放地址散列表
//类型声明
enum KindOfEntry{
legitimate,
empty,
deleted
};
struct HashEntry{
int element;
enum KindOfEntry Info;
};
typedef struct HashEntry Cell;
struct HashTableOpen{
int table_size;
Cell *TheCells;
};
//初始化例程
HashTableOpen InitializeTableOpen(int table_size){
HashTableOpen *H;
H = new HashTableOpen();
H->table_size = table_size;
H->TheCells = new Cell[table_size];
for (int i = 0; i != table_size; i++){
H->TheCells[i].Info = empty;
}
return *H;
}
//使用平方探测法的Find例程
typedef int i_position;
i_position FindOpen(int key, HashTableOpen H){
i_position current_pos = key / H.table_size;
int collision_num = 0;
while (H.TheCells[current_pos].Info != empty && H.TheCells[current_pos].element != key){
current_pos += 2 * ++collision_num - 1;
if (current_pos >= H.table_size){
current_pos -= H.table_size;
}
}
return current_pos;
}
//Insert 例程
void InsertOpen(int key, HashTableOpen H){
i_position position;
position = FindOpen(key, H);
if (H.TheCells[position].Info != legitimate){
//ok to insert
H.TheCells[position].Info = legitimate;
H.TheCells[position].element = key;
}
}
测试实例:
HashTableOpen H = InitializeTableOpen(7);
InsertOpen(5, H);
InsertOpen(7, H);
i_position p=FindOpen(7, H);
if (p != NULL){
cout << "find " << H.TheCells[p].element << endl;
}
else{
cout << "not find" << endl;
}
再散列(rehashing):如果表的元素填的太满,那么操作的运行时间将开始消耗过长,且Insert操作可能失败,解决方法是:建立另外一个大约两倍大的表,计算每个元素的新散列值并将其插入到新表中。