學習筆記 雜湊表
最近開始把之前欠的NOIP基礎知識點刷一下
2333其實我的作業還沒有寫完
做到雜湊表的時候,我有點懵,顯然前幾次講課的時候我沒有聽
於是Lbmttw_lx就開始在網上學習了
(啊啊啊 沙雕橘貓真心可愛,愛了愛了)
發現其實Hash表是個比較有趣的東西
(一種典型的空間換時間的資料結構,也叫散列表)
時間複雜度O(1)查詢
雜湊表之所以能過做到O(1)查詢,是因為它的查詢是直接按照關鍵字Key Value來的
也就是說,它將關鍵字通過某種規則對映到陣列中的某個位置,以加快查詢的速度。
雜湊表中的每一個元素,都應該有且只有一個地址。
如果兩個元素都擁有一個地址,就產生了雜湊衝突,發生衝突的不同關鍵字被稱之為同義詞。
處理雜湊衝突有很多方法,但是都是基於處理關鍵字而來的,儘可能讓關鍵字都不相同。
那麼,關鍵字是如何來的呢?其實就是雜湊函式處理得到的。
首先是雜湊函式H,H就是賦予特定元素特定的地址的函式,雜湊表則是基於雜湊函式而建立起來的查詢表
那麼問題來了,既然雜湊函式這麼好,我們如何構造它呢??
有好幾種構造雜湊函式的方法,分別是
1.直接定址法
2.數學分析法
3.平方取中法
4.摺疊法
5.除留餘數法
由於第一種 和第五種方法可能用到的比較廣泛,主要說一下這兩種吧
我是不會告訴你們剩下幾種我也不會的!
1.直接定址法
取元素的關鍵字或關鍵字的線性函式值為雜湊地址
如H(x)=x或H(x)=a*x+b(a,b都為常數)
2.除留餘數法
取關鍵字被某個不大於散列表長度 m 的數 p 求餘,得到的作為雜湊地址。
即 H(key) = key % p, p < m。
還有很多構造雜湊函式的方法,無論是什麼方法,原則都應該是
儘可能避免或減少雜湊衝突
23333上那道模板題
問題描述
給定兩個集合A、B,集合內的任一元素x滿足1 ≤ x ≤ 10^9,並且每個集合的元素個數不大於10000 個。我們希望求出A、B之間的關係。只需確定在B 中但是不在 A 中的元素的個數即可。
輸入檔案
第一行兩個數m和n分別表示集合A和集合B元素的個數。 以下兩個分別是集合A和集合B的元素。
輸出檔案
一個數,表示在B中但是不在 A 中的元素的個數。
輸入樣例
5 6
1 3 8 4 9
4 8 9 10 12 13
輸出樣例
3
限制和約定
時間限制:1s
空間限制:128MB
是不是看完部落格介紹之後覺得這道題很簡單了呢??
1 #include <bits/stdc++.h> 2 #define mo 100005 3 #define MAXN 2000000 4 using namespace std; 5 int m,n,a[MAXN],b,ans,ha[MAXN],now[MAXN]; 6 bool Hash(int i) 7 { 8 int pos=a[i]%mo+1; //除留餘數法賦予地址 9 ha[i]=now[pos]; 10 now[pos]=i; 11 } 12 bool judge(int x) 13 { 14 int pos=x%mo+1; 15 bool ju=0; 16 for(int i=now[pos];i;i=ha[i]) //類不類似於 圖論中的連結串列 17 { 18 if(a[i]==x) 19 { 20 ju=1; 21 break; 22 } 23 } 24 return ju; 25 } 26 int main() 27 { 28 cin>>m>>n; 29 for(int i=1;i<=m;i++) 30 { 31 scanf("%d",&a[i]); 32 Hash(i); 33 } 34 for(int i=1;i<=n;i++) 35 { 36 scanf("%d",&b); 37 if(!judge(b)) 38 ans++; 39 } 40 cout<<ans<<endl; 41 return 0; 42 }View Code
大概就這麼多吧!!!有錯誤麻煩及時留言,謝謝!!~~~
&n