散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
1> 哈希函数/散列函数:
直接定址法、数字分析法、平方取中法、除留余数法、随机数法
2>余除留余数法:取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址的方法数法:取关键字 H(key)=keyMOD p (p
p表示数组长度除以3/4后的最大质数
3> 哈希表长度m:数组长度除以3/4 址的方法
4>解决哈希冲突的方法:
开放定址法:线性探测法、二次探测法、伪随机探测法
再哈希法、链地址法、建立公共溢出区
5> 链地址法:将所有哈希函数值相同的记录存储在同一线性链表中
#include <stdio.h>
#include <stdlib.h>
typedef int datadef;
typedef struct Node
{
datadef data;
struct Node *next;
} *node;
int prime(int m) // 最大素数
{
for (int j = m; j >= 2; j--)
{
int count = 0;
for (int i = 2; i < m; i++)
{
if (m % i == 0)
{
count++;
}
}
if (count == 0)
{
return j;
}
}
}
void init(node hash[], int p) // 初始化
{
for (int i = 0; i < p; i++)
{
hash[i] = NULL;
}
}
void in_hash(node hash[], int p, datadef a) // 创建哈希表
{
int s = a % p;
node t = (node)malloc(sizeof(struct Node));
if (t == NULL)
{
return;
}
t->data = a;
t->next = NULL;
if (hash[s] == NULL)
{
hash[s] = t;
}
else
{
t->next = hash[s]->next;
hash[s]->next = t;
}
}
void output(node hash[], int p) // 输出
{
for (int i = 0; i < p; i++)
{
printf("[%d] : ", i);
node t = hash[i];
while (t)
{
printf("%d\t", t->data);
t = t->next;
}
printf("--NULL--\n");
}
}
void search(node hash[], int p, datadef a) // 哈希查找
{
int s = a % p;
node t = hash[s];
while (t)
{
if (t->data == a)
{
printf(" %d 存在\n", a);
return;
}
else
t = t->next;
}
printf(" %d 不存在\n", a);
}
void clean(node hash[], int p) // 哈希表释放
{
for (int i = p - 1; i >= 0; i--)
{
if (hash[i] == NULL)
{
continue;
}
node t = hash[i];
while (hash[i]->next)
{
node s = t->next;
t->next = s->next;
free(s);
s == NULL;
}
hash[i] = NULL;
}
}
int main(int argc, const char *argv[])
{
datadef a[] = {41, 24, 35, 123, 43, 21, 43, 12, 1234, 7};
int len = (sizeof(a) / sizeof(a[0]));
int m = len * 4 / 3;
int p = prime(m);
node hash[p];
init(hash, p);
for (int i = 0; i < len; i++)
{
in_hash(hash, p, a[i]);
}
output(hash, p);
datadef e;
printf("请输入你要找的元素:");
scanf("%d", &e);
search(hash, p, e);
clean(hash, p);
output(hash, p);
}