1、哈希函數進行模除取余時,最好取素數進行模除。
【解析】哈希表設計目的就是希望盡量的隨機散射,不希望這些在同一列上的元素(也就是會沖突的元素)之間具有關系,所以我們都采用素數作為哈希表的大小,從而避免模數相同的數之間具備公共因數。
① 如果用一個合數8作為哈希表大小,0-30在哈希表中的散射情況:
② 用質數7作為哈希表大小,0-30在哈希表中的散射情況:
2、哈希表裝填因子(負載因子)定義為:α= 填入表中的元素個數 / 哈希表的長度
α是哈希表裝滿程度的標志因子。由於表長是定值,α與“填入表中的元素個數”成正比,所以,α越大,填入表中的元素較多,產生沖突的可能性就越大;α越小,填入表中的元素較少,產生沖突的可能性就越小。
3、哈希函數構造主要有以下幾種:
- 1:直接尋址法;
- 2:取模法;
- 3:數字分析法;
- 4:折疊法;
- 5:平方取中法;
- 6:除留余數法;
- 7:隨機數法。
4、Hash處理沖突的方法:
① 開放地址法:在得到Hash值后如果產生沖突,則加一個增量d,直至沒有沖突的位置。
d的取法:
(1)線性探測再散列:1,2,3,4... 其實就是當發生沖突時,從該沖突位置逐個向后查找,類似於循環數組,直到找到合適的位置或者找遍整個表都未找到合適的位置。這個方法的缺點是易發生堆聚現象,堆聚就是存入哈希表的數據在表中連成一片。
【注】哈希查找中k個關鍵字具有同一哈希值,若用線性探測法將這k個關鍵字對應的記錄存入哈希表中,至少要進行(k ( k + 1 ) / 2)次探測。--- 第一次算線性探測
【注】設有n個關鍵字具有相同的Hash函數值,則用線性探測法把這n個關鍵字映射到Hash表中需要做 n * (n - 1) / 2 次線性探測? --- 第一次不算線性探測
第一個關鍵字直接插入,第二個關鍵字要做1次探測,所以類推n個關鍵詞要做0+1+2+...+(n-1) = n * (n - 1) / 2 。
(2)二次探測再散列(平方探測法):可以避免堆積問題。
【例題】設哈希表長為14,哈希函數是H(key)=key%11,表中已有數據的關鍵字為15,38,61,84共四個,現要將關鍵字為49的結點加到表中,用二次探測再散列法解決沖突,則放入的位置是( 9 )。
【解析】15%11 = 4,38%11 = 5,61%11 = 6,84%11 = 7.
要求49的位置:49%11 = 5,被占用了,使用二次探測再散列法,<1> (5+1^2)%14=6 沖突 <2> (5-1^2)%14=4 沖突 <3> (5+2^2)%14=9 不沖突,得到最終位置為9.
(3) 偽隨機探測再散列。將步長改為隨機數,這樣使不同的關鍵字具有不同的探測順序,可以有效避免堆聚。
② 再哈希表法:產生沖突時取不同的哈希函數計算,但缺點是不易產生“聚集”,增加計算時間。
③ 鏈地址法:拉鏈法處理沖突簡單,且無堆積現象,即非同義詞決不會發生沖突,因此平均查找長度較短
【例題】設散列表的長度為8,散列函數H(k)=k mod 7,初始記錄關鍵字序列為(32,24,15,27,20,13),計算用鏈地址法作為解決沖突方法的平均查找長度是(1.5)
【解析】鏈地址法作為解決沖突 方法:將所有關鍵字為同義詞的記錄存儲在一個單鏈表中,並用一維數組存放頭指針。
④ 建立一個公共溢出區。
5、Hash操作能根據散列值直接定位數據的存儲地址,設計良好的hash表能在常數級時間下找到需要的數據,但是更適合於內存中的查找。
B+樹是一種是一種樹狀的數據結構,適合做索引,對磁盤數據來說,索引查找是比較高效的
STL_Map的內部實現是一顆紅黑樹,但是只是一顆在內存中建立二叉樹,不能用於磁盤操作,而其內存查找性能也比不上Hash查找。
因此三者中,對於內存中數據,查找性能較好的數據結構是Hash_Map,對於磁盤中數據,查找性能較好的數據結構是B+Tree。
6、設哈希表長度為11,哈希函數H(K)=(K的第一個字母在字母表中的序號) MOD 11,若輸入順序為(D,BA,TN,M,CI,I,K,X,TA),采用內散列表,處理沖突方法為線性
測法,要求構造哈希表,在等概率情況下查找成功平均查找長度為:20/9 。
【解析】
散列表 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
散列元素 |
K |
TN |
BA |
M |
D |
CI |
X |
|
|
TA |
I |
查找成功次數 |
1 |
4 |
1 |
2 |
1 |
3 |
5 |
|
|
1 |
2 |
查找失敗次數 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
1 |
1 |
9 |
8 |
平均查找成功長度跟平均查找失敗長度如下:
ASL suc =(1+4+1+2+1+3+5+1+2)/ 9 = 20 / 9
ASL fail =(7+6+5+4+3+2+1+1+1+9+8)/11 = 47 / 11
①
D=4mode11=4,1次 B=2mod11=2,1次 T=20mod11=9,1次 M=13mod11=2->3,2次 C=3mod11=3->4->5,3次 I=9mod11=9->10,2次
K=11mod11=0,1次 X=24mod11=2->3->4->5->6,5次 T=20mod11=9->10->0->1,4次
9個數字,共20次,所以20/9。
②
某個(哈希表中並不存在的)值n對11取余之后,結果可能是0~10
如果n mod 11的值是8、9、10那么1次查找之后就可以判定表中不存在這個值,
如果n mod 11 = 0,那么還需要偏移,一共9次查找才能判定表中沒有這個值,
如果n mod 11 = 1,那么需要8次查找才能判定表中沒有這個值,
如果n mod 11 = 2,那么需要7次查找才能判定表中沒有這個值,……
如果n mod 11 = 7,那么需要2次查找才能判定表中沒有這個值。所以不成功的平均查找長度就是上述查找次數取均值。
7、
① 索引僅滿足“=”、“IN”和“<=>”查詢,不能使用范圍查詢因為hash索引比較的是經常hash運算之后的hash值,因此只能進行等值的過濾,不能基於范圍的查找,因為經過hash算法處理后的hash值的大小關系,並不能保證與處理前的hash大小關系對應。
② hash索引無法被用來進行數據的排序操作。由於hash索引中存放的都是經過hash計算之后的值,而hash值的大小關系不一定與hash計算之前的值一樣,所以數據庫無法利用hash索引中的值進行排序操作。
③ 對於組合索引,Hash 索引在計算 Hash 值的時候是組合索引鍵合並后再一起計算 Hash 值,而不是單獨計算 Hash 值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash 索引也無法被利用。
④ Hash 索引遇到大量Hash值相等的情況后性能並不一定就會比B-Tree索引高。對於選擇性比較低的索引鍵,如果創建 Hash 索引,那么將會存在大量記錄指針信息存於同一個 Hash 值相關聯。這樣要定位某一條記錄時就會非常麻煩,會浪費多次表數據的訪問,而造成整體性能低下。
8、哈希表(Hash Table)是一種根據關鍵字直接訪問內存存儲位置的數據結構。通過哈希表,數據元素的存放位置和數據元素的關鍵字之間建立起某種對應關系。
A,hash函數可以把字符串等任意長度的輸入映射成固定長度的整數,也就是哈希值。
C,哈希表建立了哈希值與原值信息存儲之間的聯系,可以通過哈希值查找到原值信息。
D,不同的信息產生相同的哈希值叫哈希沖突。設計哈希函數應盡量避免哈希沖突。因此一般很難沖突。
9、散列的基本思想是以結點的關鍵碼作為自變量,通過散列函數將其映射到記錄的存儲地址。有時不同的關鍵碼值經過同一散列函數計算后形成相同的存儲地址,產生碰撞現象。由於處理碰撞的代價較大,應盡量避免。這就要求散列函數在作用於各記錄關鍵碼后的取值能同等均勻在存儲空間上。
10、散列表的查找效率取決於:散列函數、處理沖突的方法和裝填因子。
11、開哈希表-------鏈式地址法,閉哈希表-------開放地址法
開哈希只會和相同值發生沖突,而閉哈希除了與相同值發生沖突,還會與不同值發生沖突。所以,開哈希不受密度影響,而閉哈希受密度影響。
12、現有一完全的P2P共享協議,每次兩個節點通訊后都能獲取對方已經獲取的全部信息,現在使得系統中每個節點都知道所有節點的文件信息,共17個節點,假設只能通過多次兩個對等節點之間通訊的方式,則最少需要(30)次通訊。【記住】2n - 4次。