當插入的時候咱們只須要經過散列函數插入到對應的鏈表中便可。
散列表的英文名叫"HASH TABLE",也叫哈希表或者HASH表。算法
散列表用的是數組支持按照下標隨機訪問的特色,其實就是一種數組的擴展,沒有數據就沒有散列表數組
例子:函數
好比說學校裏面的每一個學生都有編號,而後有89名學生去參加運動會,咱們如今要作一個經過編號迅速找到學生信息,編號是這樣的061101,06是年級,11是班級,01就是編號,這樣咱們就能夠經過取每一個編號的後兩位數做爲數組的下標把學生的信息存儲下來。blog
這裏的編號061101就是鍵或者關鍵字,這裏的取每一個編號的後兩位數的過程叫做散列函數,這裏的獲取到的01也就是數組的下標,叫做散列值string
下面是僞代碼實現的散列函數(取編號的後兩位)hash
int hash(String key) {
// 獲取後兩位字符
string lastTwoChars = key.substr(length-2, length);
// 將後兩位字符轉換爲整數
int hashValue = convert lastTwoChas to int-type;
return hashValue;
}
散列表特色:ast
1.獲得的散列值必須是非負數class
2.若是key1=key2,那麼func(key1)=func(key2)擴展
3.若是key1≠key2,那麼func(key1)≠func(key2)方法
第一點很好理解,由於數組下標是從0開始的,第二點也好理解,相同的值通過散列函數計算出來的值相同,第三點看起來也很好理解,可是其實大多數的散列函數都不能實現這個要求,就連業界有名的MD5,SHA等哈希算法,也沒法避免散列衝突。
散列衝突是什麼意思呢?
就是不一樣的值經過散列函數計算出來的散列值相同,也就是存儲的數組的下標相同,那麼就會帶來衝突
那麼解決散列衝突的方法通常有這麼兩種
1.開放尋址法
開放尋址法的核心思想是,若是出現了散列衝突,咱們就從新探測一個空閒位置,將其插入, 那如何探測空閒位置呢?咱們先來看這種線性探測的方法。
當咱們往數組中插入數據時,發現該數組下標已經被佔用,那麼咱們就依次日後面繼續查找下標,直到找到空閒的數組下標而後將其插入。
能夠看到上圖中x通過散列函數獲得數組下標爲7的位置,可是7已經被佔用了,那麼咱們就繼續日後查找,一直查到下標爲2的位置是空閒的,那麼咱們就將其插入到這個位置。
這個時候當咱們須要查找的時候就不能單純的經過散列函數查找到對應的散列值來查找數據了,而是要在比對一下存儲在該數組下標中的元素的值是否和須要查找的值同樣
2.鏈表法
這個很好理解,就是把得出來相同散列值存在一個鏈表中
當插入的時候咱們只須要經過散列函數插入到對應的鏈表中便可。