程序員常說的「哈希表」是個什麼鬼?

「哈希表」主要做用在於高效查找。算法

  在編程實現中,經常面臨着兩個問題:存儲和查找,存儲和查找的效率每每決定了整個程序的效率。編程

腦補下,你在家裏忘記了指甲刀放在哪裏,一般要在你家全部抽屜中順序尋找,直到找到,最差狀況下,有N個抽屜,你就要打開N個抽屜。這種存儲方式叫數組,查找方法稱爲「遍歷」。數組

腦補下,你是一個整理控,全部物品必須分門別類放入整理箱,再將整理箱編號,好比1號放入針線,2號放入證件,3號放入細軟。數據結構

  這種存儲和查找方式稱爲「哈希」,若是這個時候要查找護照,你不準要再翻全部抽屜,直接可在2號整理箱中獲取,一般只用一次查找便可,如何編號整理箱,稱爲哈希算法。函數

一樣是查找,差距怎麼那麼大涅~,假設咱們有100億條數據記錄,那差距就變得明顯,遍歷須要查找最多100億次,最少1次,哈希只需1次。設計

讓咱們正式介紹哈希和哈希算法,哈希也稱散列,哈希表是一種與數組、鏈表等不一樣的數據結構,與他們須要不斷的遍歷比較來查找的辦法,哈希表設計了一個映射關係f(key)= address,根據key來計算存儲地址address,這樣能夠1次查找,f既是存儲數據過程當中用來指引數據存儲到什麼位置的函數,也是未來查找這個位置的算法,叫作哈希算法。hash

  讓咱們舉個例子,好比下面這幾我的物,按數組存儲: 餘罪(133123111243)=>傅老大(13888888888)=>沈嘉文(13452342349)=>大胸姐(13890380934) 這樣我要找到大胸姐的電話號碼,須要順序查找對比整個數組,第一個餘罪,不是,第二個不是,第三個不是,直到第四個找到大胸姐。效率

  若是以hash存儲呢?首先讓咱們來看看如何設計哈希算法,哈希算法能夠隨意設計,教科書上通常會說如下幾種方法:直接定址發,平方取中法,除數取餘法,哈希算法的本質上是計算一個數字,若是用這幾種方法講解會稍顯晦澀,咱們假設咱們的哈希算法是取姓名的首字母。因此f(餘罪) = y, f(傅老大) = f,f(沈嘉文) = s,f(大胸姐) = d。 構建的hash表以下: a b c y .133123111243 d .13890380934 g z 位置7 f .13888888888 s .13452342349 咱們看到他們分別以姓名首字母的位置插入到這一張表格中,這樣咱們構建了這樣一個Key-Value表格,此表就是哈希表,也稱爲Hash Table。將來,當咱們要查找餘罪的時候,經過計算,餘罪在y位置,能夠經過1次查找,找到這條記錄,也即手機號。遍歷

這個時候有客官問了,那以首字母爲哈希函數的話,應該有不少好比以y的姓名啊,這個時候就不是一次查找了吧,其實有不少條記錄都映射到一個位置上,稱爲哈希衝突。程序

哈希衝突是跟哈希函數的設計正相關的,你的隨機性越大,那麼產生哈希衝突的可能性越小,在小几率下,若是還有衝突怎麼辦,這個時候要作些有損的設計,好比若是有兩個首字母爲y的姓名,那麼能夠接到餘罪的後面,當查找的時候,須要先查找到y,而後再順序查找,以下所示: a b c y .133123111243 1332232323于謙 d .13890380934 g z 位置7 f .13888888888 s .13452342349 還有一些解決哈希衝突的辦法叫「哈希再哈希」,也就是針對第一次哈希的結果再進行一次hash來減少衝突的機率。

   這就是Hash表,首先Ta是一種數據結構,是一種效率極高的查找方式,哈希表的核心在於哈希函數的設計,哈希衝突了沒關係,咱們要增長隨機性以及對衝突進行適當的有損化的處理。

相關文章
相關標籤/搜索