前言:面試常常被問到"你瞭解哈希嗎?",今天就來作一下梳理總結面試
1.什麼是哈希函數
散列技術是把 記錄的存儲位置和它的關鍵字之間 創建一個肯定的對應關係f,使每一個關鍵字 key 對應一個 存儲位置 f(key),
而這個f函數就是哈希函數數據結構
2.什麼是哈希表
採用哈希函數把記錄存儲在一塊 連續的存儲空間中,這塊連續的存儲空間就稱爲 散列表或者哈希表(hash table)。
key是關鍵字,f(key)是存放記錄的散列地址。dom
3.哈希表查找的適用範圍
散列技術是一種存儲方法,也是一種查找方法。最適用的範圍是查找與給定關鍵字 相等的記錄。函數
4.哈希表是怎麼經過查找的關鍵字key定位到數據的
根據指定的key,用哈希函數進行運算,等到的就是存放數據的地址。
好的哈希函數要符合:計算時間要比其餘查找技術用時少,散列地址分佈均勻
(1)直接定址法:適用於 事先知道關鍵字的分佈狀況,且查找表較小並連續。性能
f(key) = a * key +b 舉個例子,好比要統計80後出生年份的人口數,此時函數爲 f(key) = key -1980 (2)數字分析法: 適用於 關鍵字位數比較大的狀況並預先知道關鍵字的分佈且若干位分佈較均勻 關鍵字:抽取,從關鍵字中抽取一部分來計算散列存儲的位置方式 好比手機號前三位是接入號,中間四位表示用戶的歸屬地,後四位纔是真正的用戶號 能夠對後四位進行反轉(1234->4321),右環位移(1234->4123)等等方法
(3)平方取中法 :適用於 不知道關鍵字分佈,而位數不是很大的時候指針
假設關鍵字是1234,那它平方就是1522756,再抽中間3位 227,用做散列地址。
(4)摺疊法:適用於 事先不知道關鍵字的分佈,適合關鍵字位數較多的狀況code
它是將關鍵字 從左到右分割成 位數相等的幾部分(最後一部分能夠短一些),而後將這幾部分用加法求和,而且按照散列表的表長,取最後幾位做爲散列地址 舉例:9876543210,散列表長度爲3位,把它分爲四組 987,654,321,0,而後疊加求和 987+654+321+0 = 1962 取後面三位 即 962
(5)除留餘數法(此方法爲最經常使用的構造散列函數的方法)hash
f(key) = key mod p (p<=m) mod就是求餘數的意思,這個方法不只能夠對關鍵字取模,也能夠在進行摺疊,平方取中後再取模 本方法的關鍵在於 選取 合適的 p,若是p選的很差就容易產生同義詞 p的選取方法:若是散列表的長度爲m,則 p <= m(最好接近m) 的最小質數或者不包含小於20質因子的合數。 (6)隨機數法 :適用於 關鍵字的長度不等的場景 選擇一個隨機數,取關鍵字的隨機函數值做爲它的散列地址即, f(key) = random(key)
在採用不一樣的哈希函數的時候主要考慮如下幾點:
關鍵字的長度
散列表的大小
計算散列地址所需的時間
關鍵字的分佈狀況
記錄查找的頻率table
5.爲何會有哈希衝突,怎麼解決哈希衝突
當 關鍵字 key1 不等於 key2,可是分別用f(key1) f(key2)等到兩個相同的地址,這種現象就叫作衝突,並把key1和key2稱爲這個散列函數的同義詞。
怎麼解決衝突?
(1)開放地址法:即一旦發生了衝突,就去尋找下一個空的散列地址,只要散列表足夠大,空的散列地址總能找到並將記錄存入。效率
公式:f(key) = (f(key) + di) mod m (di = 1,2,3,......, m-1)
咱們把這種解決衝突的開放地址法稱爲線性探測法,像碰到key1和key2通過哈希函數計算後並無衝突,可是還要爭奪一個地址的狀況稱爲堆積。
還有一種狀況,當發生衝突後,當前地址的後續都沒有空位置,可是前面還有一個空位,儘管能夠繼續日後+1來找到空位置,可是效率不好。
因此在線性探測法的基礎上進行二次探測法,即,對di 進行平方,這樣它就能夠往回找了
f(key) = (f(key) + di) mod m (di = 1^2, -1^2,2^2,-2^2m..., q^2, -q^2, q <= m/2)
(2)再散列函數法
再散列地址法就是事先準備多個散列函數,好比摺疊,平方取中,除留餘數,每當發生散列地址衝突的時候,就換一個散列函數計算 這種方法可以使關鍵字不彙集,可是也相應增長了計算的時間
(3)鏈地址法
就是把全部關鍵字爲同義詞的記錄存放在一個單鏈表中,散列表只存儲這個鏈表的頭指針 這樣的話不管有多少個衝突,都只是在當前位置給單鏈表增長節點,可是同時也帶來了查找時須要遍歷單鏈表的性能損耗
(4)公共溢出區法
把衝突的值用新的一張溢出表來保存,在查找的時候,先和基本表相應的位置進行比對,若是相等,則查找成功 不相等則到溢出表去順序查找。若是相對基本表而言,有衝突的數據不多的狀況下,公共溢出區的結構對查找性能仍是能夠的
6.哈希表查找的時間複雜度是多少(沒有哈希衝突的理想狀態下),在有哈希衝突的狀況下,散列查找的平均查找時間取決於什麼呢?
散列表是幾乎全部查找中效率最高的,由於它的時間複雜度是 o(1)
在非理想狀態下 散列函數的平均查找時間取決於
(1)散列是否均勻
(2)處理衝突的方法:線性探測法可能會產生堆積,顯然沒有二次探測法好,而鏈地址發處理衝突則不會產生堆積,於是具備更佳的平均查找性能。
參考來源:《大話數據結構》