哈希表
我们将任意类型元素转换为整型的过程叫作哈希。
所谓哈希,实质上是高维空间向低维空间的映射。高维度空间元素数量多,低维空间元素数量少,必定会出现多对一的映射,所以必然出现哈希冲突。在设计哈希函数的过程要针对状态数来进行分析。
哈希函数的本质在做哈希,处理哈希碰撞。
设计哈希表应当注重以下两点:
- 设计哈希函数
- 处理冲突
设计哈希有以下几种方法:
- 开放地址法
- 多重哈希
- 拉链法
- 建立公共溢出区
字符串Hash
APHash代码演示:
int APHash(const char *str) {//基于位运算的字符串哈希
int hash_value = 0;
for (int i = 0; str[i]; ++i) {
if (i & 1) {
hash_value ^= (hash_value << 7) ^ str[i] ^ (hash_value >> 3);
}else {
hash_value ^= (~((hash_value << 11) ^ str[i] ^ (hash_value >> 5)));
}
}
return hash_value & 0x7fffffff;
}
BKDRHash代码演示:
int BKDRHash(const char *str) { //基于数值运算的字符串哈希
int hash_value = 0, seed = 131;// prime to 256
for (int i = 0; str[i]; ++i) {
hash_value = hash_value * seed + str[i];
}
return hash_value & 0x7fffffff;
}
ZobristHash代码演示:
int zobrist_table[50][256] = {0};//基于矩阵数值运算的字符串哈希
void init_zobrist_table() {
for (int i = 0; i < 50; ++i) {
for (int j = 0; j < 256; ++j) {
zobrist_table[i][j] = rand();
}
}
return;
}
int ZobristHash(const char *str) {
static int flag = 1;
if (flag) {
flag = 0;
init_zobrist_table();
}
int hash_value = 0;
for (int i = 0; str[i]; ++i) {
hash_value ^= zobrist_table[i][str[i]];
}
return hash_value & 0x7fffffff;
}