1.开地址法
当冲突产生时生成一个探查序列,检索沿探查序列进行。最简单的方法是进行线性探查,即每次向下一个单元探查。
探查过程终止的三种情况
1.若当前探查的单元为空,则表示查找失败,若是插入,则将key记录下来。
2.若当前探查的元素单元中含有key,则查找成功,但对于插入则意味着失败。
3.若探查到d-1仍未发现空单元或找到key值,则查找,插入均失败。
#include<bits/stdc++.h>
using namespace std;
#define M 30
typedef struct HashNode
{
int data;
int isNull;
}HashTable;
HashTable hashTable[M];
int hash(int key)//hash函数
{
return key%10007;
}
int insert(int key)//向表中插入元素
{
int x=hash(key);
if(!hashTable[adress].isNull)
{
hashTable[adress].data=x;
hashTable[adress].isNull=1;
}
else
{
while(hash[adress].isNull==1&&adress<=M+x-1)
adress++;
if(adress==M+x)
return -1;
hashTable[adress%M].data=key;
hashTable[adress%M].isNull=1;
}
return 0;
}
int find(int key)//查找
{
int x=hash(key);
adress=x;
while(!(hashTable[adress].isNull==1&&hashTable[adreess].data=key&&adress<=M+x-1))
adress++;
if(adress==M+x)
adress=-1;
return adress%M;
}
int main()
{
return 0;
}
2.拉链法
用拉链法处理冲突时要求为哈希表的每个节点增加一个link,用于连接同义词子表 。
大致来说,同义词子表有两种,一种是在基本存储区域外开辟一个溢出区存储它,另一种则是借助基本存储区域内尚未被占用的空间,以下代码采用的是从后往前的查找空格单元
#include<bits/stdc++.h>
using namespace std;
struct node
{
int key;
int link;
}table[10005];
int hash(int x)
{
return x%10007;
}
int main()
{
int m=hash(k);
if(table[m].key==0)
{
table[m].key=k;
table[m].link=-1;
}
int r=m;
else
{
while(table[m].key!=k&&table[m].link!=-1)
{
m=table[m].link;
if(table[i].key==k)//查找成功
cout<<"Yes"<<endl;
else
{
while(r>=0&&table[r].key!=0) do r--;
if(r<0) cout<<"Overflow"<<endl;//hash表溢出
else
{
table[m].link=r;
table[r].key=k;
table[r].link=-1;
}
}
}
}
}
变量r的初值赋为m,则table[r]到table[m-1]的区域内所有单元都已被占用。