哈希表HashMap

没用的定义

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

问题引入

很简单的例子
给一列数
然后询问这个数字有没有出现过

solution

数组跑,对于过大的下标,或者极大值,正确性不能保证
map每次查询(O(logn))
哈希表查询为(O(1))

HASH MAP

hash函数跳过不说
最简单的就是((a*key + b) % mod)
对于hashmap再取一个小的mod数
看例子看例子
给一列数的hash值为

54 43 42 22

假定取小mod=11

10 10 9 0

然后建图
0 9 10
22 42 43
54

然后像临接表一样存储
例如查询43时

for(int i = head[43 % mod]; i; i = edge[i].nxt){
      if(edge[i].val == 43) return 1;
}

就完了,确实比map快好多
开O2之后差距不大

code

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define int long long
using namespace std;

inline int read(){
	int x = 0, w = 1;
	char ch = getchar();
	for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return x * w;
}

const int mod = 23333;
const int ss = 1000010;

struct node{
	int nxt, val;
}edge[ss + 5];

int head[ss + 5], tot;

inline void add(int u){
	int sol = u % mod;
	edge[++tot].val = u;
	edge[tot].nxt = head[sol];
	head[sol] = tot;
}

inline bool find(int u){
	int sol = u % mod;
	for(int i = head[sol]; i; i = edge[i].nxt){
		if(edge[i].val == u)
			return 1;
	}
	return 0;
}

inline void erase(int u){
	head[u % mod] = 0;
}

inline unsigned long long hash(int u){
	u *= 233;
	u %= mod;
}

signed main(){
	int n = read();
	for(int i = 1; i <= n; i++){
		int x = read();
		add(hash(x));
	}
	int cnt = read();
	while(cnt--){
		int x = read();
		if(find(hash(x))) puts("AC");
		else puts("WA");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/rui-4825/p/13637908.html