Hash
核心思想:
- 以常数时间完成查找
基本问题:
- 如何把关键字Key映射到它存放的位置?(Hash函数)
- 两个关键字位置相同时怎么处理?(冲突解决)
Hash函数
整数的Hash函数
- 直接定址法
- H(key) = a x key + b
除留余数法
- H(key) = key % p
- p最好是素数
数字分析法
- 适用于手机号、身份证号等
- 可以先存成字符串,用atoi()将某些位变成整数,或者key[i]-‘0’的方法
- 折叠法、平方取中法等
- 直接定址法
字符串的Hash函数
- 移位法
- 移位法
Index Hash(const char * Key, int TableSize)
{
unsigned int HashVal = 0;
while (*Key != '\0') {
HashVal = (HashVal << 5) + *Key++;
}
return HashVal;
}
处理冲突(collision)
- 开放定址法
换个位置放
- 线性探测法(Linear probing)
- 平方探测法
- 双散列、再散列等
- 分离链接法
将冲突的关键字存储在一个单链表中
typedef struct ListNode *Position;
struct ListNode {
ElementType Element;
Position Next;
}
typedef Position List;
struct HashTbl {
List *TheLists;
int HashTable;
};
typedef struct HashTbl *HashTable;
HashTable CreateTable(int TableSize)
{
HashTable H;
H = new HastTbl;
H->TableSize = NextPrime(TableSize);
H->TheLists = new List[H->TableSize];
for (int i = 0; i != H->TableSize; ++i) {
H->TheLists[i] = new ListNode;
H->TheLists[i]->Next = nullptr;
}
return H;
}