本片博客主要講的是哈希表中簡單的衝突處理的方法,以及命中率計算。原理方面基本沒有講解,基本就講個方法,主要用於知識記錄以及幫助一些刷題玩家瀏覽。函數
簡而言之,不講技術,只講方法。測試
寫這篇博客的契機是在刷pat甲級題遇到了一道寫哈希的題目,結果英文太次被欺負了。以後靠翻譯讀懂題目,結果被命中率給坑了,遙想起之前打比賽好像也被這個坑過,憤懣不平來寫博。spa
相關參考:https://blog.csdn.net/xyzbaihaiping/article/details/51607770.net
相關題目:PAT (Advanced Level) Practice -- 1145 Hashing - Average Search Time (25 分)翻譯
hash:音譯哈希,意譯散列,用於在規定大小的表中,快速插入和查找數據。code
衝突處理分紅大類和小類,大類爲開散列方法( open hashing,也稱爲拉鍊法,separate chaining ) 和 閉散列方法( closed hashing,也稱爲開地址方法,open addressing )。blog
開散列我沒寫過,不提了,之後被坑可能會補。ip
閉散列最經常使用的兩個:線性探測(Linear probing) 和 二次探測(Quadratic probing)。(英文苦逼注意下,沙雕博主看不懂二次和探測的英文,結果卡題卡半天啊。看下混個眼熟)
博客
key = Hash(key) + 1數學
key = Hash(key) + 2 以此類推。說明:hash(key)就是構造哈希的方法。
若是是餘數法,並且是來回探測的話:
key =(Hash(key) + 1) % size
key =(Hash(key) - 2 + size) % size 以此類推
探測係數一直到size爲止,那麼也就是直到表滿都放得下
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徐州站和去年的青島站有感而發