哈希函數(shù)的選擇至關(guān)重要,一個好的哈希函數(shù)應(yīng)滿足三個標(biāo)準(zhǔn):1. 均勻性:將鍵均勻分布到各桶中,避免某些桶過載而降低查找效率;2. 高效性:計算哈希值的速度要快,以保證整體操作性能;3. 確定性:相同鍵始終映射到相同桶,確保哈希表的正確性。常見哈希函數(shù)包括除留余數(shù)法(適用于整數(shù)鍵,建議表長為質(zhì)數(shù))、乘法哈希法(對鍵分布不敏感,需選合適常數(shù))和字符串專用函數(shù)如djb2、fnv-1a等;實際應(yīng)用中可根據(jù)鍵類型選擇合適方法,或使用murmurhash、cityhash等高性能庫。桶的實現(xiàn)主要有鏈地址法和開放尋址法:1. 鏈地址法用鏈表存儲同桶鍵值對,實現(xiàn)簡單但鏈過長時查找退化;2. 開放尋址法通過線性探測、二次探測或雙重哈希尋找空桶,節(jié)省空間但易聚集且實現(xiàn)復(fù)雜。沖突解決還可采用再哈希法(用備用哈希函數(shù))或公共溢出區(qū)(集中存放沖突元素),但各有空間與效率權(quán)衡。unordered_map平均時間復(fù)雜度為o(1),最壞情況為o(n),性能依賴于哈希函數(shù)質(zhì)量與沖突處理策略;適用于需高效增刪查、鍵可哈希且無需有序的場景;若需有序遍歷或鍵不支持哈希,則應(yīng)使用map,其基于紅黑樹實現(xiàn),時間復(fù)雜度穩(wěn)定為o(log n),但速度較慢且內(nèi)存占用通常低于unordered_map;此外,unordered_map因需額外結(jié)構(gòu)支持桶管理,內(nèi)存開銷較大,在資源受限環(huán)境下應(yīng)謹(jǐn)慎使用。
unordered_map哈希表通過哈希函數(shù)將鍵映射到桶,然后將鍵值對存儲在相應(yīng)的桶中。當(dāng)查找時,再次使用哈希函數(shù)找到桶,然后在桶內(nèi)搜索鍵。
哈希表的核心在于哈希函數(shù)和桶。哈希函數(shù)負(fù)責(zé)將鍵轉(zhuǎn)換為桶的索引,而桶則負(fù)責(zé)存儲實際的鍵值對。理想情況下,哈希函數(shù)應(yīng)該將不同的鍵均勻地分布到不同的桶中,以避免沖突。然而,實際情況中,沖突是不可避免的。
哈希函數(shù)的選擇至關(guān)重要。一個好的哈希函數(shù)應(yīng)該滿足以下幾個標(biāo)準(zhǔn):
均勻性:哈希函數(shù)應(yīng)該將鍵均勻地分布到所有桶中,避免出現(xiàn)某些桶過于擁擠,而另一些桶空閑的情況。這直接影響到哈希表的查找效率。如果鍵都集中在少數(shù)幾個桶中,那么查找操作的時間復(fù)雜度將接近 O(n),其中 n 是鍵的數(shù)量。
高效性:哈希函數(shù)應(yīng)該盡可能快地計算出哈希值。哈希表的性能很大程度上取決于哈希函數(shù)的計算速度。復(fù)雜的哈希函數(shù)雖然可能提供更好的均勻性,但會增加計算開銷。
確定性:對于相同的鍵,哈希函數(shù)應(yīng)該始終返回相同的哈希值。這是哈希表能夠正確工作的基本要求。如果哈希值不穩(wěn)定,那么查找操作將無法找到正確的鍵值對。
常見的哈希函數(shù)包括:
除留余數(shù)法:將鍵除以哈希表的大小,取余數(shù)作為哈希值。這是一種簡單且常用的哈希函數(shù),但需要選擇合適的哈希表大小,以避免沖突。例如,可以選擇一個質(zhì)數(shù)作為哈希表的大小。
乘法哈希法:將鍵乘以一個常數(shù),然后取結(jié)果的小數(shù)部分,再乘以哈希表的大小,取整數(shù)部分作為哈希值。這種方法對鍵的分布不太敏感,但需要選擇合適的常數(shù)。
字符串哈希函數(shù):對于字符串類型的鍵,可以使用各種字符串哈希函數(shù),例如 DJB2、FNV-1a 等。這些哈希函數(shù)通常會將字符串的每個字符都參與計算,以產(chǎn)生一個哈希值。
選擇哈希函數(shù)時,需要根據(jù)實際情況進(jìn)行權(quán)衡。例如,如果鍵的類型是整數(shù),且范圍較小,那么除留余數(shù)法可能是一個不錯的選擇。如果鍵的類型是字符串,那么可以選擇一個專門為字符串設(shè)計的哈希函數(shù)。此外,還可以考慮使用一些現(xiàn)成的哈希函數(shù)庫,例如 Google 的 CityHash、MurmurHash 等。這些庫通常提供了高性能和高質(zhì)量的哈希函數(shù)。
桶的實現(xiàn)方式主要有兩種:
鏈地址法:每個桶存儲一個鏈表,鏈表中存儲所有哈希到該桶的鍵值對。當(dāng)發(fā)生沖突時,新的鍵值對會被添加到鏈表的末尾。鏈地址法的優(yōu)點是實現(xiàn)簡單,缺點是當(dāng)鏈表過長時,查找效率會下降。
開放尋址法:當(dāng)發(fā)生沖突時,按照某種規(guī)則在哈希表中尋找下一個空閑的桶,并將鍵值對存儲在該桶中。常見的開放尋址法包括線性探測、二次探測、雙重哈希等。開放尋址法的優(yōu)點是節(jié)省空間,缺點是實現(xiàn)較為復(fù)雜,且容易產(chǎn)生聚集現(xiàn)象。
解決哈希沖突的方法有很多,除了鏈地址法和開放尋址法之外,還可以使用:
再哈希法:當(dāng)發(fā)生沖突時,使用另一個哈希函數(shù)重新計算哈希值,直到找到一個空閑的桶。這種方法的優(yōu)點是可以減少聚集現(xiàn)象,缺點是需要額外的哈希函數(shù)。
建立公共溢出區(qū):將所有沖突的鍵值對存儲在一個公共的溢出區(qū)中。這種方法的優(yōu)點是實現(xiàn)簡單,缺點是當(dāng)溢出區(qū)過大時,查找效率會下降。
選擇哪種沖突解決方法,需要根據(jù)實際情況進(jìn)行權(quán)衡。例如,如果鍵的數(shù)量較少,且哈希函數(shù)能夠較好地分散鍵,那么可以使用開放尋址法。如果鍵的數(shù)量較多,且容易發(fā)生沖突,那么可以使用鏈地址法或再哈希法。
unordered_map
unordered_map
應(yīng)該在以下情況下使用
unordered_map
如果需要鍵值對的順序,或者鍵的類型不支持哈希函數(shù),那么應(yīng)該使用
map
map
另外,需要注意的是,
unordered_map
map
unordered_map
以上就是unordered_map哈希表怎么工作 桶與哈希函數(shù)機(jī)制的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
每個人都需要一臺速度更快、更穩(wěn)定的 PC。隨著時間的推移,垃圾文件、舊注冊表數(shù)據(jù)和不必要的后臺進(jìn)程會占用資源并降低性能。幸運的是,許多工具可以讓 Windows 保持平穩(wěn)運行。
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號