-
哈希表概念
决定一个哈希表的主要是哈希函数与处理冲突的方法。而按照设定的哈希函数和处理冲突的方法将一组关键字key 映射到有限的地址集合中,这就是哈希表。可以根据处理冲突的方法不同,给哈希表不同的命名,如:链式哈希表,开放址哈希表。 -
哈希函数构造方法
直接定义法:代码块如下:
int hash1(int key){
return a*key + b; //a 缩放, b 平移
}
除留取余法:(我接触最多的)
区间长度为 m 的哈希表,取 不大于 m 的数 x 为模, H(key) = key % p。(理论上,p 取最接近 m 的素数最好了)
int hash2(int key){
return key % p;
}
数字分析法:了解不多,貌似没用到过。
折叠法:
移位折叠
int hash3(int key){
itn i , j= 1, qu , sum = 0;
for (i = 0; i < w; i++)
j * = 10;//按照w 位分割
while (key != 0){
qu = key % j;
sum += qu;
key /= j;
}
return sum;
}
平方取中法 :接触的很少(没有)
- 处理冲突
当关键字key的数量大于哈希地址的元素个数时,就一定会产生冲突(几个不同的key 在同一个哈希地址)可以理解为一个关于x , y 的函数, x (key)不同时 , y (地址)是相同的 ,x1 != x2, 但是H(x1) = H(x2),这就是冲突。
处理冲突的方法:
链地址法:关键字为同一个地址的链接在同一个单链表中。
开放地址法:
Hi=(H(key)+di)% m ( i=1,2,…,n)
1,线性探测:如果这个地址已经有元素了,就到下一个地址,直到找到空地址或者浏览完全表。
di = 1,2,3……
2,二次探测:左右跳跃的看
di = 12,-12,22-22…… - 哈希表的实现
1,开放地址哈希表(在论坛看了大佬的代码,然后自己思考写了一份,用的是线性探测)
#include <stdio.h>
#include <stdlib.h>
//宏定义相关常量
#define Max 10
#define Size 10
typedef struct Sqlist{
int *data;
int length;//长度
}Sqlist;//顺序表
typedef struct HashSqlist{
int *data;
int length;
}HashSqlist