基本思想:
cuckoo hash是一種解決hash沖突的方法,其目的是使用簡單的hash 函數來提高hash table的利用率,同時保證O(1)的查詢時間
基本思想是使用2個hash函數來處理碰撞,從而每個key都對應到2個位置。
插入操作如下:
1. 對key值hash,生成兩個hash key值,hashk1和 hashk2, 如果對應的兩個位置上有一個為空,那么直接把key插入即可。
2. 否則,任選一個位置,把key值插入,把已經在那個位置的key值踢出來。
3. 被踢出來的key值,需要重新插入,直到沒有key被踢出為止。
我們先來看看cuckoo hashing有什么特點,它的哈希函數是成對的(具體的實現可以根據需求設計),每一個元素都是兩個,分別映射到兩個位置,一個是記錄的位置,另一個是 備用位置。這個備用位置是處理碰撞時用的,這就要說到cuckoo這個名詞的典故了,中文名叫布谷鳥,這種鳥有一種即狡猾又貪婪的習性,它不肯自己築巢, 而是把蛋下到別的鳥巢里,而且它的幼鳥又會比別的鳥早出生,布谷幼鳥天生有一種殘忍的動作,幼鳥會拼命把未出生的其它鳥蛋擠出窩巢,今后以便獨享“養父 母”的食物。借助生物學上這一典故,cuckoo hashing處理碰撞的方法,就是把原來占用位置的這個元素踢走,不過被踢出去的元素還要比鳥蛋幸運,因為它還有一個備用位置可以安置,如果備用位置上 還有人,再把它踢走,如此往復。直到被踢的次數達到一個上限,才確認哈希表已滿,並執行rehash操作。如下圖所示(圖片來源):
我們不禁要問發生哈希碰撞之前的空間利用率是多少呢?不幸地告訴你,一維數組的哈希表上跟其它哈希函數沒什么區別,也就50%而已。但如果是二維的呢?
一個改進的哈希表如下圖所示,每個桶(bucket)有4路槽位(slot)。當哈希函數映射到同一個bucket中,在其它三路slot未被填滿 之前,是不會有元素被踢的,這大大緩沖了碰撞的幾率。筆者自己的簡單實現上測過,采用二維哈希表(4路slot)大約80%的占用率(CMU論文數據據說 達到90%以上,應該是擴大了slot關聯數目所致)。
摘自:http://coolshell.cn/articles/17225.html