Hash(哈希/散列)表中衝突處理及命中計算

前言

  本片博客主要講的是哈希表中簡單的衝突處理的方法,以及命中率計算。原理方面基本沒有講解,基本就講個方法,主要用於知識記錄以及幫助一些刷題玩家瀏覽。函數

  簡而言之,不講技術,只講方法。測試

引言

  寫這篇博客的契機是在刷pat甲級題遇到了一道寫哈希的題目,結果英文太次被欺負了。以後靠翻譯讀懂題目,結果被命中率給坑了,遙想起之前打比賽好像也被這個坑過,憤懣不平來寫博。spa

  相關參考:https://blog.csdn.net/xyzbaihaiping/article/details/51607770.net

  相關題目:PAT (Advanced Level) Practice -- 1145 Hashing - Average Search Time (25 分)翻譯

前綴知識

  hash:音譯哈希,意譯散列,用於在規定大小的表中,快速插入和查找數據。code

  構造哈希表的幾種方法:
    1.直接定址法(取關鍵字的某個線性函數爲哈希地址)
    2.除留餘數法(取關鍵值被某個不大於散列表長m的數p除後的所得的餘數爲散列地址)
    3.平方取中法(關鍵字平方後,取中間一段數字)
     4.摺疊法
    5.隨機數法
    6.數學分析法
  經常使用方法是 直接定址法除留餘數法
  通常作的題目都是喜歡本身寫哈希的,簡單並且好控制 由於題目要求。直接定址題目通常會給你方法的,在此講餘數法。

衝突處理

  衝突處理分紅大類和小類,大類爲開散列方法( open hashing,也稱爲拉鍊法,separate chaining )  閉散列方法( closed hashing,也稱爲開地址方法,open addressing )blog

  開散列我沒寫過,不提了,之後被坑可能會補。ip

  閉散列最經常使用的兩個:線性探測(Linear probing)  二次探測(Quadratic probing)。(英文苦逼注意下,沙雕博主看不懂二次和探測的英文,結果卡題卡半天啊。看下混個眼熟)
博客

  1、線性探測

    key = Hash(key) + 1數學

    key = Hash(key) + 2    以此類推。說明:hash(key)就是構造哈希的方法。

   若是是餘數法,並且是來回探測的話:

    key =(Hash(key) + 1) % size

    key =(Hash(key) - 2 + size) % size     以此類推

   探測係數一直到size爲止,那麼也就是直到表滿都放得下

  2、二次探測

    key = Hash(key) + 1*1

    key = Hash(key) + 2*2    以此類推

   若是是餘數法,並且是來回探測的話:

    key =(Hash(key) + 1*1) % size

    key =(Hash(key) - 2*2 + size) % size     以此類推

   探測係數一直到size爲止,若是路上查到的key都有數據的話,那麼這個數據沒法放入(題目特殊要求按題目定)

命中計算

  其實沒什麼難度,主要是被坑了不爽無能狂怒rua

  按構表法和衝突處理法進行查找,沒進行一次查找,查找次數+1,若是當前的查找那個位置是空的話,表明找不到,那麼結束

  若是衝突係數一直到size還沒找到,那麼超過size的那次判斷也算做一次查找  

//msize是表的容量
for(j=0;j<msize;j++) {
    cnt++;
        //沒有找到或者找到了都算結束了
    if(a[(x%msize + j*j) % msize] == 0) break;
    if(a[(x%msize + j*j) % msize] == x) break;
}
//衝突處理完的這個判斷,也算一次查找
if(j == msize) cnt++;
//除以總數,算平均值
printf("%.1lf\n",cnt*1.0/m);

  其實這個命中率並無什麼明確的規定,在此提出只是表示 「啊,這麼狗的命中率也有啊」 的感想。刷題時(無論是比賽仍是測試),都要隨機應變,依靠樣例去猜出題人的想法,今天可能出界+1,明天就可能沒查到不算一次查詢。

後記

  感謝看到這麼後面,這算是很胡鬧的博文。比賽中技術知識只決定七成的結果,剩下的英語水平、碼力和運氣佔的更多

  看到最近icpc徐州站和去年的青島站有感而發

相關文章
相關標籤/搜索