哈希表支持的一種最有效的檢索方法:散列.數組
因爲計算哈希值和在數組中進行索引都只消耗固定時間,所以哈希表的最大亮點在於他是一種運行時間在常量級的檢索方法.函數
哈希表主要有兩種:編碼
1.鏈式哈希表:將數據存儲在桶中的哈希表,每一個桶裏面都是一個鏈表,且鏈表的容量隨着衝突的增大而增大.(換句話說就是若是有衝突,會在桶中的鏈表加上一個存儲的值)spa
2.開地址哈希表:將數據存在表自己,而不是在桶中,他經過各類探查方法來避免衝突.索引
解決衝突:循環
無論在以上那種哈希表中,咱們的目標是儘量均勻的分配表中的元素.因此咱們必須選擇正確和哈希函數.方法
在鏈式哈希表中,哈希函數能夠表示爲:鏈表
h(k)=x數據
通常來講,大多數的散列方法都假設鍵值k爲整數,因此,若是設置鍵值須要把傳入的類型進行轉換.時間
哈希函數可使用:
取餘法:
h(k)= k mod m (其中k表示轉換後的整數,m表示哈希表的桶數)
好比:有m=11個位置,k爲25,獲得桶的索引index=25%11=3,因此在bucket[index]的位置存入值.
通常來講,須要避免m的值是2的冪,一般選擇一個素數.
乘法:
h(k)= m(kA mod 1),
他將整數k乘以一個常數A(0<A<1),取結果的小數部分,而後乘以m取結果的整數部分.一般狀況下,A取0.618,他是由√‾5減1除以2獲得.
這個方法的有點是在取m得時候不須要啊那麼慎重.
最後,若是仍是有衝突的元素在一個桶內,哈希表會用鏈式結構存儲衝突元素.
開地址哈希表
因爲元素放在表自己,沒有鏈式結構存儲衝突元素,哈希表須要其餘方法解決衝突.
線性探查:開地址哈希表中一種簡單的探查方法就是探查表中的連續槽位.
表示爲:若是存在i(0<i<m-1)
h(k,i)= (h'(k)+i) mod m
其中h'(k)可使用上述的取餘法.
大體步驟:
1.i=0,經過h'(k)找到一個位置,若是位置沒有元素,就存儲元素.
2.若是有元素,i+1來查看這個位置的下個位置是否有元素.
3.循環1,2步驟.
這個方法的主要缺點是元素不能均勻散列.
雙散列:
最有效的探查的方法,就是經過計算兩個輔助哈希函數哈希編碼的和來獲得哈希編碼.
表示爲:若是存在i(0<i<m-1)
h(k,i)=(h1(k)+ih2(k)) mod m
h1和h2是兩個輔助哈希函數.
通常來講:m的值取素數,而後令h1(k)= k mod m,h2(k)=1+(k mod m'),其中m'略小於m,通常取m'=m-1或者m-2;
這種方法的優勢是能在表中探查併產生較好的元素分佈,缺點是必須限制m的值.這樣才能保證在一系列探查中訪問表中全部槽以後纔會再次探查任何槽.