1. 程式人生 > >雜湊表(散列表)

雜湊表(散列表)

雜湊表有時候也被稱作散列表,它是怎麼來的呢?在之前我們介紹過了順序表,他的查詢是O(1)的,但是他的刪除和插入是O(n)的,雖然雙端連結串列的按照節點的刪除和插入是O(1)的,但是他的按值查詢是O(n)的,其實都不是很理想,那麼有沒有刪除和查詢都很快的資料結構呢?

這個時候就有了雜湊表。

雜湊表是什麼原理呢?

舉個例子,如果我們這裡有一個數組,他包含13個元素,我們先定義一個簡單的雜湊函式,就用插入元素的值對13取模運算,然後我們拿到取模的值按照該值進行相同的索引插入,但是插了幾個數字之後我們發現不同的插入元素有著相同的取模運算的結果,那麼就遇到了我們的第一個問題,也就是雜湊衝突,怎麼解決呢?可能有些同學已經想到了,我們再通過加入一點演算法讓這個取模運算後的值變大或者變小,總之就是讓該取模值找到一個空的位置可以插入,科學家就在此基礎上提出了三種解決方法,分別是線性探查、二次探查和雙重雜湊,三者本質上都是在原有基礎上對取模值加上某值再次進行取模運算(還有一種傳統方法,就是對衝突的值的位置上建立一個連結串列結構,但是資料大了是不可取的,這裡不多介紹),這個時候我們再次插值,但是快結束的時候我們發現數組大小不夠用了,基於這個科學家又提出了負載因子的概念,負載因子說的普通點就是要插入的元素除以陣列的大小,一般負載因子大小超過80%的時候我們就要進行重雜湊操作,重雜湊就是擴大陣列的大小,這個由個人決定了,Cpython一般是擴大兩倍。

雜湊表本質上就是這樣一個東東,在實現的時候我們要注意一點,也就是插槽的三種狀態,第一種是從來沒有被插入過元素的,第二種是插入過元素然後被刪除的,第三種是已經被插入值的槽。為什麼要把第二種拿出來說呢?因為我們在某個槽插入節點後,把該槽的節點刪除的時候,他的key和value是none,在查詢值的過程中是無法判斷我們要搜尋的值是否等於none的,因為none是無法判斷的。