哈希表能使数据通过一种映射方式存放到一种范围更小的数据空间中,比如-1e9~1e9, 存放到1e5的空间中, 并且能够快速实现存放和查找的操作,删除的话一般很少,可以看作是一次查找,找到之后打一个标记,即为删除
实现方式
- 开放寻址法
a为一个整数
b = a%m
把a放在角标为b的数组中,当发生冲突时,即之前有元素已经占据了b这个位置,则向后移动,直至找到一个空位置
注:m为一个质数时,冲突的可能性最小 - 拉链法
a为一个整数
b = a%m
把a放在角标为b的数组中,当发生冲突时,在b这个位置后面拉一条链,即链表,继续存放
模板题
- 利用拉链法实现
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+3;
int n;
int h[N], e[N], ne[N], idx;
int insert(int x){
int k = (x%N+N)%N;
e[idx] = x;
ne[idx] = h[k];
h[k] = idx++;
}
bool query(int x){
int k = (x%N+N)%N;
for(int i=h[k]; i!=-1; i=ne[i]){
if(e[i] == x) return true;
}
return false;
}
int main(){
memset(h, -1, sizeof h);
scanf("%d", &n);
while(n--){
char op[2];
int x;
scanf("%s%d", op, &x);
if(op[0] == 'I') insert(x);
else {
if(query(x)) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}
开放寻址法实现
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+3;
int h[N], n, null = 0x3f3f3f3f;
int insert(int x){
int k = (x%N+N)%N;
while(h[k] != null && h[k]!= x){
k++;
if(k == N) k=0;
}
return k;
}
int main(){
memset(h, 0x3f, sizeof h);
scanf("%d", &n);
while(n--){
char op[2];
int x;
scanf("%s%d", op, &x);
int k = insert(x);
if(op[0] == 'I'){
h[k] = x;
}
else{
if(h[k] == x) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}