1. 程式人生 > >學習筆記 雜湊表

學習筆記 雜湊表

最近開始把之前欠的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