哈希表(Hash Table)與哈希算法


概述

  哈希表(Hash Table)也叫做散列表,根據關鍵碼值(key value)可以快速存取訪問的一種空間換時間的數據結構。它通過把關鍵碼值通過映射函數計算到表中一個位置來訪問記錄,可以加快查找到速度。這個映射函數叫做散裂函數(Hash Function),存放記錄的數組叫做哈希表(或散列表)。

  舉個例子比如我們想想在14億個身份證號碼中找出其中一個身份證號,我們肯定不可能一個個去找,而我們可以將14億條數據存放在哈希表中,然后根據哈希表結構就可以快速找到要找的數據。所以哈希表就是這種能夠通過給定的關鍵字的值直接訪問到具體對應的值的一個數據結構。也就是說把關鍵字映射到一個表中的位置來直接訪問記錄,以加快訪問速度。

  我們把這個關鍵字稱為 Key,把對應的記錄稱為 Value,它們是一一對應的。

 

 哈希表的應用

   1. 在編程語言中,如Golang中的字典(map),PHP里的數組(array),Java中的Map等它們底層都是使用哈希表來實現的。

   2. Redis中的字典及鍵值對存放。

   3. 緩存(Lru Cache)。

 

哈希表工作原理

  

 

   哈希表是根據哈希函數來決定你要存放的數據所在的位置。上圖字符串lies傳遞給哈希函數,經過計算返回給的下標是9,那么就講lies存放在9這個下標的位置,其它的存放都是這樣的過程。

   這里面最重要的就是上面這個哈希函數,因為哈希函數決定數據應該被存放在什么地方。有很多種哈希函數,其中一種比較簡單的:把要存儲的數據每個字符的ASCII碼相加,再去除余(mod)某個數,余數就是存儲的位置。當然現實中的哈希函數比這個復雜多,而且哈希函數的性能比較好的話,可以讓計算出來的值比較分散,而不會發生碰撞,比如有可能兩個不同的數據,但是最后計算出來的位置相同,像上圖lies字符串計算后得到9,那么其它的字符串計算后也有可能等於9,這種情況就稱為“哈希碰撞”

 

哈希算法

  哈希表之所以這么高效,可以快速從海量數據中查到某一條數據,這其中就使用到了哈希算法。我們知道哈希表的工作機制是根據Key訪問一個映射表來得到 Value 的地址,而這個映射表就叫作散列函數或者哈希函數,實現該函數的算法就是哈希算法。

 

常見哈希算法

  1. 直接尋址法(direct-address table):取關鍵字或關鍵字的某個線性函數值為散列地址。

  2. 數字分析法:通過對數據的分析,發現數據中沖突較少的部分,並構造散列地址。例如同學們的學號,通常同一屆學生的學號,其中前面的部分差別不太大,所以用后面的部分來構造散列地址。

  3. 平方取中法 (midsquare method) :當無法確定關鍵字里哪幾位的分布相對比較均勻時,可以先求出關鍵字的平方值,然后按需要取平方值的中間幾位作為散列地址。這是因為:計算平方之后的中間幾位和關鍵字中的每一位都相關,所以不同的關鍵字會以較高的概率產生不同的散列地址。

  4. 取隨機數法:使用一個隨機函數,取關鍵字的隨機值作為散列地址,這種方式通常用於關鍵字長度不同的場合。

  5. 除留取余法:取關鍵字被某個不大於散列表的表長 n 的數 m 除后所得的余數 p 為散列地址。這種方式也可以在用過其他方法后再使用。該函數對 m 的選擇很重要,一般取素數或者直接用 n。

 

 哈希表性能分析

   哈希表的性能是由其選擇的哈希算法決定的,哈希表之所以查找中效率很高,是因為它的時間復雜度為O(1),但是也不是總是為O(1),因為在實際使用中,隨着數據量的增大,數據沖突是不可避免的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM