哈希表的基本操作
散列(hash)表/哈希表
1.关键字和和存储的地址建立一个对应的关系:Add = Hash(key);
2. 解决冲突方法:
(1)开放定址法 – 探测方式:线性探测、二次探测。
(2)再哈希法
(3)分离链接法 – 利用链表的方式。
(4)公共溢出区法
3.存储结构:用顺序存储来构建哈希表。构建结构数组
注意:使用不同的哈希函数得到的冲突次数不同。
----------------------------------------------------------------------
除留余数法与开放定址法构建哈希表:
定义哈希表类型:
typedef datatype{
int key;
int hi; //表示本该存储的位置到最后存储的位置的冲突次数
}
typedef HashTable{
datatype *base; //指向表的指针
int length; //表长
int num; //表内元素个数
}hashtable; //哈希表
void createhashtable(hashtable H,int m,hash[]){ //m为表长,hash数组存储要存进哈希表的元素
H->base=(datatype *)malloc(m*sizeof(datatype)); //构建哈希表
if(!H->base)return -1;
H->length=m;
for(i=0;i
H->base[i]->key=0;
H->base[i]->hi=-1; //表中单元空的标志
}
for(i=0;i
adrr=hash[i]%p; //哈希函数,除留余数法,p自选
sum=0; //记录冲突次数
if(H->base[adrr]->hi==-1){
H->base[adrr]->key==hash[i];
H->base[adrr]->hi=0;
}
else{
do{
adrr=(adrr+k)%m; //线性探测再散列
sum+1;
}while(H->base[adrr]->hi!=-1);
H->base[adrr]->key=hash[i];
H->base[adrr]->hi=sum;
}
}
H->num=m;
}
------------------------------------------------------
在哈希表查中找元素:
void searchhash(hashtable H,int x){
adrr=x%p; //哈希函数
id=adrr;
while(H->base[adrr]->hi!=-1){ //在哈希表中查找,遇到空单元就退出。因为若遇到空单元还没找到,则该元素一定不存在
if(H->base[adrr]->key==x)
return adrr;
else{
adrr=(adrr+k)%H->length; //线性探测
}
if(adrr==id) //整个哈希表没有空单元,遍历一遍还没找到则退出
break;
}
return -1;
}
--------------------------------------------------------
在哈希表中插入一个元素(比创建哈希表插入元素多了判定是否表满)
void Inserthashtable(hashtable H,int x)
{
int adrr,temp;
adrr=hash(x); // 计算x的哈希地址
temp=adrr; //temp暂存x的哈希地址
sum=0;
if(H->base[adrr]->hi==-1)
{
H->base[adrr]->key=x;
H->base[adrr]->hi==0;
}
else{
sum++;
do{
adrr=(adrr+k)%H->length; //进行线性探测
if(adrr==temp){
printf("哈希表已满\n"); // 哈希表已满
exit(1); //退出
}
}while(H->base[adrr]->hi!=-1);
H->base[adrr]->key=x;
H->base[adrr]->hi=sum;// 插入k
}
}
----------------------------------------------------
//从哈希表中删除元素(在遍历查找哈希表基础上进行删除)
void searchhash(hashtable H,int x){
adrr=x%p; //哈希函数
id=adrr;
while(H->base[adrr]->hi!=-1){ //在哈希表中查找,遇到空单元就退出。因为若遇到空单元还没找到,则该元素一定不存在
if(H->base[adrr]->key==x){
H->base[adrr]->key=0;
H->base[adrr]->hi=-1;
}
else{
adrr=(adrr+k)%H->length; //线性探测
}
if(adrr=id) //整个哈希表没有空单元,遍历一遍还没找到则退出
break;
}
printf("没有找到该节点");
return -1;
}