1. 雜湊表的定義
給定表m,存在函式f(key),對任意給定的關鍵字值key,代入函式後若能得到包含該關鍵字的記錄在表中的位址,則稱表m為雜湊(hash)表,函式f(key)為雜湊(hash) 函式。
2. 雜湊表的用途
把乙個較大範圍的值域對映到乙個較小的範圍
3. 雜湊表的原理
通過對大數取餘運算把乙個大數對映到乙個較小的範圍,若取餘結果有衝突則進行處理
4. 兩種儲存結構
根據對出現衝突時的不同處理方式,把雜湊表分為兩類:開放定址法、拉鍊法
5. 兩種模板
(
1) 拉鍊法
int h[n]
, e[n]
, ne[n]
, idx;
// 向雜湊表中插入乙個數
void
insert
(int x)
// 在雜湊表中查詢某個數是否存在
bool
find
(int x)(2
) 開放定址法
int h[n]
;// 如果x在雜湊表中,返回x的下標;如果x不在雜湊表中,返回x應該插入的位置
intfind
(int x)
return t;
}
6. 例題:模擬雜湊表
維護乙個集合,支援如下幾種操作:
1、「i x」,插入乙個數x;
2、「q x」,詢問數x是否在集合**現過;
現在要進行n次操作,對於每個詢問操作輸出對應的結果。
輸入格式
第一行包含整數n,表示運算元量。
接下來n行,每行包含乙個操作指令,操作指令為」i x」,」q x」中的一種。
輸出格式
對於每個詢問指令「q x」,輸出乙個詢問結果,如果x在集合**現過,則輸出「yes」,否則輸出「no」。
每個結果佔一行。
資料範圍
1≤n≤105
−109≤x≤109
輸入樣例:
5i 1
i 2i 3
q 2q 5
輸出樣例:
yesno
開放定址法題解
原理:把陣列開成原本資料範圍的2
~3倍,如果有衝突就把衝突的數一次向後排
#include
#include
using
namespace std;
//n為實際資料範圍10^5的兩倍,同樣取質數
//null為在資料範圍之外的乙個大數,用於標記某個陣列元素中是否為空
const
int n =
200003
, null =
0x3f3f3f3f
;int h[n]
;//儲存原資料
// 函式功能:查詢某個資料在雜湊錶即(h[n])中應該存放的下標
intfind
(int x)
return k;
}int
main()
}return0;
}
拉鍊法題解
原理:在每個陣列元素處拉一條單鏈表,儲存不同的值
#include
#include
using
namespace std;
const
int n =
100003
;//此處設為大於對映範圍最小的質數,為了減少衝突
//h[n]儲存所有煉表頭, 下標為原資料對映後的值
//e[n]儲存鍊錶資料, 即原資料
//ne[n]儲存鍊錶指標
//idx記錄當前鍊錶中節點的個數
int h[n]
, e[n]
, ne[n]
, idx;
//函式功能:在雜湊表中插入乙個數
void
insert
(int x)
// 函式功能:查詢乙個數是否在雜湊表中
bool
find
(int x)
intmain()
}return0;
}
7. 字串雜湊
(1)原理:把乙個字串看成乙個p進製數,然後把它轉化為10進製,再對他取餘進行對映
(2)雜湊步驟:
1.把乙個字串看成是131或13331進製的數(這樣衝突概率小)
2.把這個p進製數轉化為對應的10進製數
3.把轉化後的10進製數對264取餘,進行對映
(3)注意:不能把字母對映成0,因為如果是0那麼a和aa都會是0;假定我們對映後的數不會發生衝突。
(4)**步驟:
預處理p[n]、h[n],p[i]儲存pi,h[i]儲存字串前i個數的十進位制數
字串字首:h[i] = h[i-1] * p + str[i], 任意子串 = h[r] - h[l - 1] * pr-l+1
詢問區間,比較兩個區間對應的字串的十進位制數是否相等
8. 模板
核心思想:將字串看成p進製數,p的經驗值是131或13331,取這兩個值的衝突概率低
小技巧:取模的數用2
^64,這樣直接用unsigned
long
long儲存,溢位的結果就是取模的結果
typedef
unsigned
long
long ull;
ull h[n]
, p[n]
;// h[k]儲存字串前k個字母的雜湊值, p[k]儲存 p^k mod 2^64
// 初始化p[0
]=1;
for(
int i =
1; i <= n; i ++
)// 計算子串 str[l ~ r] 的雜湊值
ull get
(int l,
int r)
9.例題:字串雜湊
給定乙個長度為n的字串,再給定m個詢問,每個詢問包含四個整數 l1,r1,l2,r2 ,請你判斷[ l1,r1 ]和[ l2,r2 ]這兩個區間所包含的字串子串是否完全相同。
字串中只包含大小寫英文本母和數字。
輸入格式
第一行包含整數n和m,表示字串長度和詢問次數。
第二行包含乙個長度為n的字串,字串中只包含大小寫英文本母和數字。
接下來m行,每行包含四個整數 l1,r1,l2,r2 ,表示一次詢問所涉及的兩個區間。
注意,字串的位置從1開始編號。
輸出格式
對於每個詢問輸出乙個結果,如果兩個字串子串完全相同則輸出「yes」,否則輸出「no」。
每個結果佔一行。
資料範圍
1≤n,m≤105
輸入樣例:
8 3aabbaabb
1 3 5 7
1 3 6 8
1 2 1 2
輸出樣例:
yesno
yes
#include
using
namespace std;
typedef
unsigned
long
long ull;
const
int n =
100010
, p =
131;
int n, m;
char str[n]
;ull h[n]
, p[n]
;//用unsign long long 儲存,如果結果溢位則相當於對2^64取餘
//函式功能:計算任意子串的十進位制值
ull get
(int l,
int r)
intmain()
while
(m--
)return0;
}
模擬雜湊表 字串雜湊
模擬雜湊表 引入雜湊表就是根據乙個關鍵值key進行高效訪問的資料結構,可以通過雜湊函式把乙個資料當做key進行對映得到乙個儲存位址從而進行訪問。比如想要查詢100個數字範圍在 1 1e8 查詢它們是否有重複的值,那麼就可以用雜湊表來解決這個問題。對於小的數字我們就會習慣的會去乙個陣列進行標記,但是對...
資料結構 雜湊表(模擬雜湊表和字串雜湊)
維護乙個集合,支援如下幾種操作 i x 插入乙個數x q x 詢問數x是否在集合 現過 現在要進行n次操作,對於每個詢問操作輸出對應的結果。輸入格式 第一行包含整數n,表示運算元量。接下來n行,每行包含乙個操作指令,操作指令為 i x q x 中的一種。輸出格式 對於每個詢問指令 q x 輸出乙個詢...
資料結構 雜湊表(雜湊表)hash table
hash table 在計算機中,雜湊表 是 一種實現了關聯陣列 抽象資料型別的資料結構,這種資料結構可以對映 鍵 key 和 值 value 補充 關聯陣列 在電腦科學中,乙個關聯陣列 associative array 對映 map 符號表 symbol table 或者是字典 dictiona...