散列表(Hash table,也叫哈希表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它經過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫作散列函數,存放記錄的數組叫作散列表。node
很簡單的例子
給一列數
而後詢問這個數字有沒有出現過ios
數組跑,對於過大的下標,或者極大值,正確性不能保證
map每次查詢\(O(logn)\)
哈希表查詢爲\(O(1)\)數組
hash函數跳過不說
最簡單的就是\((a*key + b) % mod\)
對於hashmap再取一個小的mod數
看例子看例子
給一列數的hash值爲數據結構
54 43 42 22
假定取小mod=11函數
10 10 9 0
而後建圖
0 9 10
22 42 43
54spa
而後像臨接表同樣存儲
例如查詢43時code
for(int i = head[43 % mod]; i; i = edge[i].nxt){ if(edge[i].val == 43) return 1; }
就完了,確實比map快好多
開O2以後差距不大get
#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; }