哈希表的有优点很多,最重要的就是速度快。
然而再好的东西也是有缺点的,无疑哈希表是基于数组的,这就带来了扩展的问题。有两个解决办法1,保证你的数组够大,不会溢出 2,动态重新分配
哈希表的构造方法有许多,如直接寻址法,除法散列法,乘法散列法。。。。
解决冲突的方法有:开发地址法,再哈希法,链地址法,建立公共溢出区
下面提供一个除法散列法和链地址法结合的哈希实现。
#include <stdio.h>
#include <stdlib.h>
struct date
{
int date;
struct date *next;
};
void create_hash(char *hash[],int a[],int n)
{
int i;
for(i=0;i<n;i++)
{
int sequence=a[i]%7;
struct date *nu=(struct date*)malloc(sizeof(struct date));
nu->date=a[i];
nu->next=0;
if(hash[sequence]==0)
hash[sequence]=(char*)nu;
else
{
struct date *p=(struct date*)hash[sequence];
while(p->next!=0)
p=p->next;
p->next=nu;
}
}
}
void print_hash(char *hash[],int n)
{
int i=0;
for(;i<n;++i)
{
printf("\t%d :",i);
if(hash[i]==0)
;
else
{
struct date *p=(struct date*)hash[i];
do{
printf("%d ->",p->date);
}while(p->next!=0&&(p=p->next)); //注意这里的&&
}
printf("NULL\n");
}
printf("\n");
}
int find_hash(char *hash[],int nu)
{
int sequence=nu%7;
if(hash[sequence]==0)
return -1;
else
{
struct date *p=(struct date*)hash[sequence];
do{
if(p->date==nu)
return 1;
}while(p->next!=0&&(p=p->next));
return -1;
}
}
//从哈希表中删除元素
int remove_hash(char *hash[],int nu) //-1 no this nu ;1 remove ok
{
if(find_hash(hash,nu)==-1)
return -1;
int sequence=nu%7;
struct date *p=(struct date*)hash[sequence];
if(p->date==nu)
{
hash[sequence]=(char*)p->next;
free(p);
return 1;
}
while(p->next!=0)
{
if(p->next->date==nu)
{
struct date *tmp=p->next;
p->next=p->next->next;
free(tmp);
return 1;
}
p=p->next;
}
}
int main()
{
char *hash_table[7]={0};
int a[10]={1,10,13,9,30,15,2,18,8,20};
create_hash(hash_table,a,10);
print_hash(hash_table,7);
if(find_hash(hash_table,30)!=-1)
printf("\t30,find!!!\n\n");
remove_hash(hash_table,30);
remove_hash(hash_table,10);
print_hash(hash_table,7);
}
结果: