哈希表
hash表又称散列表,由Hash函数(散列函数)与链表结构共同实现。与离散思想类似,对复杂信息进行统计,可以用hash函数将复杂信息映射到一个容易维护的值域内,同时需要处理hash函数映射的值产生冲突的情况。
模拟散列表
散列表-散列函数:
int k = (k%N+N)%N;//N为数据范围的上阈值
避免哈希冲突的方案:
拉链法
#include<iostream>
using namespace std;
#include<cstring>
int n;
char ch;
const int N=1e5+10;
int idx, e[N], ne[N], h[N];
void insert(int x){
//hash函数找到映射值
int k = (x%N+N)%N;
e[idx] = x;
ne[idx] = h[k];
h[k] = idx++;
}
bool find(int x){
//hash函数找到映射值
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);
cin>>n;
int x;
while(n--){
cin>>ch>>x;
//cout<<ch<<" "<<x<<endl;
if(ch=='I'){
insert(x);
}
else if(ch=='Q'){
if(find(x)){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
}
return 0;
}
开放寻址法
#include <cstring>
#include <iostream>
using namespace std;
//开放寻址法一般开 数据范围的 2~3倍, 这样大概率就没有冲突了
const int N = 2e5 + 3; //大于数据范围的第一个质数
const int null = 0x3f3f3f3f; //规定空指针为 null 0x3f3f3f3f
int h[N];
int find(int x) {
int t = (x % N + N) % N;
while (h[t] != null && h[t] != x) {
t++;
if (t == N) {
t = 0;
}
}
return t; //如果这个位置是空的, 则返回的是他应该存储的位置
}
int n;
int main() {
cin >> n;
memset(h, 0x3f, sizeof h); //规定空指针为 0x3f3f3f3f
while (n--) {
string op;
int x;
cin >> op >> x;
if (op == "I") {
h[find(x)] = x;
} else {
if (h[find(x)] == null) {
puts("No");
} else {
puts("Yes");
}
}
}
return 0;
}