Campus Guider校園導航系統 Hash算法分析

Campus Guider校園導航系統是一款簡單的Windows 8平臺應用,開發過程中採用Hash表存儲校園地點列表,現筆者將項目中的hash算法分析記錄如下。

本項目中Hash算法有兩條設計思路,兩條思路的主要區別在於對衝突處理的方法不同。對於Hash函數H(key)來說,key是漢字字符串。而Hash表的長度和填充因子是相同的。首先,經過數據的收集、統計和整理後,最終確定了校園中142個地點作爲應用中的原始數據,將表長確定爲347,那麼由此計算得的填充因子爲0.409。表長由實際數據個數的兩倍再乘以係數1.25計算後所得值,再向取一個比該值小的素數而得,即142*2*1.25=355,然後取一個表長下限301,從[301,355]的素數集合中選取衝突產生少、聚集度小的素數(即將這個素數預設爲表長後進行Hash造表並觀察結果),將其確定爲表長。用此法是因爲,本項目中的數據都是預知的,可以進行多次測試選取比較好的結果。下面敘述兩種設計思路。


思路一 採用開放定址的線性探測再散列的方法處理衝突

Hash函數爲:

       當key>2時H(key)=((int)key[1]+(int)key[2]+di)/347(取第2和第3個漢字計算,值爲unicode值)di=1,2,3…;

       當key=2時H(key)=( (int)key[0]+(int)key[1]+di)/347(取第1和第2個漢字計算,值爲unicode值)di=1,2,3…;

       由於key是地名,所以不存在單字的情況。

       衝突產生時di將加1,依次向後探測空閒地址。

這種方法造表結果如下圖所示。Hash函數運算和處理衝突的總次數爲211,即在查找成功時,此方法的平均查找長度ASL=211/142。在6處產生了數據聚集(5個及以上數據連續),涉及到53條記錄,若目標關鍵字的Hash地址落在此區域將導致查找效率下降。

 

思路二 採用二次Hash和公共溢出區的方法處理衝突

Hash函數爲

    當key>2時H(key)=((int)key[1]+ (int)key[2])*1.618033/277(取第2和第3個漢字計算,值爲unicode值);

       當key=2時H(key)=( (int)key[0]+(int)key[1])/275+2(取第1和第2個漢字計算,值爲unicode值);

       由於key是地名,所以不存在單字的情況。

       衝突處理:第一次處理,先由key=2時的Hash函數計算得Hash地址,若該地址空間則存儲;否則,將該地址記爲code,然後進行判斷

       當code<138時,code=code/4+277;

       當code>=138時,code=(code-138)/4+312。

       通過這兩步取得當前記錄在公共溢出區的存儲地址。

    其中乘數因子1.618033是爲了使得生成的Hash表更加均勻,定義Hash表的後70位空間爲公共溢出區,記錄先通過往前277個地址中存放,若不成功,則將前277個地址中的前138個地址中產生衝突的記錄存放至公共溢出區的前35個地址中,後前277個地址中的後139個地址中產生衝突的記錄存放至公共溢出區的後35個地址中。即對一條記錄的關鍵字的處理被限制爲3次,至多三次可將一條記錄存入Hash表。這種方法造表結果如下圖所示。Hash函數運算和處理衝突的總次數爲195,即在查找成功時,此方法的平均查找長度ASL=195/142。所有142條記錄均已加入Hash表。在查找失敗時,任意地址至多計算比較三次即可確定失敗,即這種方法即定了查找失敗的查找長度。相對上思路一中,在6處數據聚集段(假設每處5條記錄聚集),其查找失敗的近似平均查找長度爲ASL=(6*(6+2)*5/20/(6*5)=4。而在本思路中,查找失敗時,近似平均查找長度爲ASL=(6*5*3)/(6*5)=3。觀察下圖可可,在公共溢出區中存儲了10條記錄,其填充因子αL=1/7,約爲0.143,在前277個存儲地址中有132條數據,其填充因子αM=132/277,約爲0.477,總填充因子仍爲0.409。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章