手写哈希表
也就是 leetcode 706. 设计哈希映射
采用拉链法,定义一组链表头,相同哈希值的放在同一个链表
不管是查找、插入还是删除,都需要遍历一遍对应的链表 (可以用二叉树或跳表优化)
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
struct HashNode{
int key;
int val;
HashNode *next;
HashNode(int k, int v):key(k),val(v),next(NULL){}
};
struct HashMap{
static const int M = 6007;
HashNode* head[M];
int count; // 节点编号
HashMap(){
count = 0;
for(int i = 0; i < M; i++){
head[i] = new HashNode(-1, -1);
}
}
void put(int key, int value){ // 添加或更新
int hash = key % M;
HashNode *p = head[hash]->next, *pre = head[hash];
while(p != NULL){
if(p->key == key){
p->val = value;
return;
}
pre = p;
p = p->next;
}
pre->next = new HashNode(key, value);
count++;
}
int get(int key){
int hash = key % M;
HashNode *p = head[hash]->next;
while(p != NULL){
if(p->key == key){
return p->val;
}
p = p->next;
}
return -1;
}
void remove(int key){
int hash = key % M;
HashNode *p = head[hash]->next;
HashNode *pre = head[hash];
while(p != NULL){
if(p->key == key){
pre->next = p->next;
delete p;
count--;
return;
}
pre = p;
p = p->next;
}
}
};
int main() {
HashMap hm;
hm.put(1, 1);
hm.put(2, 2);
hm.put(3, 3);
cout << hm.get(1) << endl;
cout << hm.get(2) << endl;
cout << hm.get(3) << endl;
hm.remove(1);
cout << hm.get(1) << endl;
hm.put(2, 10);
cout << hm.get(2) << endl;
}
还有一种开放定址法,当发生碰撞时,寻找下一个空闲单元,这要求负载因子比较小(0.75以下)
冲突处理四种方法(开放定址法,分离链接法,再哈希法,建立公共溢出区)
开放定址法四种方法(线性探测法,平方探测法,双散列探测法,再散列)
参考 https://cloud.tencent.com/developer/article/1672781
这里使用线性探测法,也就是顺序往下变量
点击查看代码
struct HashMap2{
static const int M = 6007;
HashNode* head[M];
int count; // 节点编号
HashMap2(){
count = 0;
for(int i = 0; i < M; i++){
head[i] = new HashNode(-1, -1);
}
}
void put(int key, int value){ // 添加或更新
int hash = key % M;
while(head[hash]->key != key && head[hash]->key != -1){
if(head[hash]->key == key){
head[hash]->val = value;
return;
}
hash = (hash + 1) % M;
}
head[hash]->key = key;
head[hash]->val = value;
count++;
}
int get(int key){
int hash = key % M;
while(head[hash]->key != key && head[hash]->key != -1){
hash = (hash + 1) % M;
}
if(head[hash]->key == key){
return head[hash]->val;
}
return -1;
}
void remove(int key){
int hash = key % M;
while(head[hash]->key != key && head[hash]->key != -1){
hash = (hash + 1) % M;
}
if(head[hash]->key == key){
// int val = head[hash]->val;
head[hash]->key = -1;
count--;
}
}
};
个性签名:时间会解决一切