日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

Python 哈希表的實(shí)現(xiàn)——字典

來源: 責(zé)編: 時(shí)間:2023-11-28 09:37:23 269觀看
導(dǎo)讀哈嘍大家好,我是咸魚接觸過 Python 的小伙伴應(yīng)該對(duì)【字典】這一數(shù)據(jù)類型都了解吧雖然 Python 沒有顯式名稱為“哈希表”的內(nèi)置數(shù)據(jù)結(jié)構(gòu),但是字典是哈希表實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)在 Python 中,字典的鍵(key)被哈希,哈希值決定了鍵對(duì)

哈嘍大家好,我是咸魚pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

接觸過 Python 的小伙伴應(yīng)該對(duì)【字典】這一數(shù)據(jù)類型都了解吧pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

雖然 Python 沒有顯式名稱為“哈希表”的內(nèi)置數(shù)據(jù)結(jié)構(gòu),但是字典是哈希表實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

在 Python 中,字典的鍵(key)被哈希,哈希值決定了鍵對(duì)應(yīng)的值(value)在字典底層數(shù)據(jù)存儲(chǔ)中的位置pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

那么今天我們就來看看哈希表的原理以及如何實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的 Python 哈希表pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

ps:文中提到的 Python 指的是 CPyhton 實(shí)現(xiàn)pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

何為哈希表(hash table)

pfz28資訊網(wǎng)——每日最新資訊28at.com

哈希表(hash table)通常是基于“鍵-值對(duì)”存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

哈希表的鍵(key)通過哈希函數(shù)轉(zhuǎn)換為哈希值(hash value),這個(gè)哈希值決定了數(shù)據(jù)在數(shù)組中的位置。這種設(shè)計(jì)使得數(shù)據(jù)檢索變得非常快pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

舉個(gè)例子,下面有一組鍵值對(duì)數(shù)據(jù),其中歌手姓名是 key,歌名是 valuepfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

如果我們想要將這些鍵值對(duì)存儲(chǔ)在哈希表中,首先需要將鍵的值轉(zhuǎn)換成哈希表的數(shù)組的索引,這時(shí)候就需要用到哈希函數(shù)了pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

哈希函數(shù)是哈希表實(shí)現(xiàn)的主要關(guān)鍵,它能夠處理鍵然后返回存放數(shù)據(jù)的哈希表中對(duì)應(yīng)的索引pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

一個(gè)好的哈希函數(shù)能夠在數(shù)組中均勻地分布鍵,盡量避免哈希沖突(兩個(gè)鍵返回了相同的索引)pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

哈希函數(shù)是如何處理鍵的,這里我們創(chuàng)建一個(gè)簡(jiǎn)易的哈希函數(shù)來模擬一下(實(shí)際上哈希函數(shù)要比這復(fù)雜得多)pfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

這個(gè)簡(jiǎn)易版哈希函數(shù)將歌手名(即 key)首字母的 ASCII 值與哈希表大小取余,得出來的值就是歌名(value)在哈希表中的索引pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

那這個(gè)簡(jiǎn)易版哈希函數(shù)有什么問題呢?聰明的你一眼就看出來了:容易出現(xiàn)碰撞。因?yàn)椴煌逆I的首字母有可能是一樣的,就意味著返回的索引也是一樣的pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

例如我們假設(shè)哈希表的大小為 10 ,我們以上面的歌手名作為鍵然后執(zhí)行 simple_hash(key, 10) 得到索引pfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

可以看到,由于Juice WRLD 和 J.cole 的首字母都一樣,哈希函數(shù)返回了相同的索引,這里就發(fā)生了哈希碰撞pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

雖然幾乎不可能完全避免任何大量數(shù)據(jù)的碰撞,但一個(gè)好的哈希函數(shù)加上一個(gè)適當(dāng)大小的哈希表將減少碰撞的機(jī)會(huì)pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)出現(xiàn)哈希碰撞時(shí),可以使用不同的方法(例如開放尋址法)來解決碰撞pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

應(yīng)該設(shè)計(jì)健壯的哈希函數(shù)來盡量避免哈希碰撞pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

我們?cè)賮砜雌渌逆I,Kanye 通過 simple_hash()  函數(shù)返回 index 5,這意味著我們可以在索引 5 (哈希表的第六個(gè)元素)上找到 其鍵 Kanye 和值Come to lifepfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

哈希表優(yōu)點(diǎn)

在哈希表中,是根據(jù)哈希值(即索引)來尋找數(shù)據(jù),所以可以快速定位到數(shù)據(jù)在哈希表中的位置,使得檢索、插入和刪除操作具有常數(shù)時(shí)間復(fù)雜度 O(1) 的性能pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

與其他數(shù)據(jù)結(jié)構(gòu)相比,哈希表因其效率而脫穎而出pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

不但如此,哈希表可以存儲(chǔ)不同類型的鍵值對(duì),還可以動(dòng)態(tài)調(diào)整自身大小pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

Python 中的哈希表實(shí)現(xiàn)pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

在 Python 中有一個(gè)內(nèi)置的數(shù)據(jù)結(jié)構(gòu),它實(shí)現(xiàn)了哈希表的功能,稱為字典pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

Python 字典(dictionary,dict)是一種無序的、可變的集合(collections),它的元素以 “鍵值對(duì)(key-value)”的形式存儲(chǔ)pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

字典中的 key 是唯一且不可變的,這意味著它們一旦設(shè)置就無法更改pfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

在底層,Python 的字典以哈希表的形式運(yùn)行,當(dāng)我們創(chuàng)建字典并添加鍵值對(duì)時(shí),Python 會(huì)將哈希函數(shù)作用于鍵,從而生成哈希值,接著哈希值決定對(duì)應(yīng)的值將存儲(chǔ)在內(nèi)存的哪個(gè)位置中pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

所以當(dāng)你想要檢索值時(shí),Python 就會(huì)對(duì)鍵進(jìn)行哈希,從而快速引導(dǎo) Python 找到值的存儲(chǔ)位置,而無需考慮字典的大小pfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

可以看到,我們通過方括號(hào)[key]來訪問鍵對(duì)應(yīng)的值,如果鍵不存在,則會(huì)報(bào)錯(cuò)pfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

為了避免該報(bào)錯(cuò),我們可以使用字典內(nèi)置的 get() 方法,如果鍵不存在則返回默認(rèn)值pfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

在 Python 中實(shí)現(xiàn)哈希表pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

首先我們定義一個(gè) HashTable 類,表示一個(gè)哈希表數(shù)據(jù)結(jié)構(gòu)pfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

在構(gòu)造函數(shù) __init__() 中:pfz28資訊網(wǎng)——每日最新資訊28at.com

  • size 表示哈希表的大小
  • table是一個(gè)長(zhǎng)度為 size 的數(shù)組,被用作哈希表的存儲(chǔ)結(jié)構(gòu)。初始化時(shí),數(shù)組的所有元素都被設(shè)為 None,表示哈希表初始時(shí)不含任何數(shù)據(jù)

pfz28資訊網(wǎng)——每日最新資訊28at.com

在內(nèi)部函數(shù) _hash() 中,用于計(jì)算給定 key 的哈希值。它采用給定鍵 key 的第一個(gè)字符的 ASCII 值,并使用取余運(yùn)算 % 將其映射到哈希表的索引范圍內(nèi),以便確定鍵在哈希表中的存儲(chǔ)位置。pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

然后我們接著在 HashTable 類中添加對(duì)鍵值對(duì)的增刪查方法pfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

其中,set() 方法將鍵值對(duì)添加到表中,而 get() 該方法則通過其鍵檢索值。該 remove() 方法從哈希表中刪除鍵值對(duì)pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在,我們可以創(chuàng)建一個(gè)哈希表并使用它來存儲(chǔ)和檢索數(shù)據(jù):pfz28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

前面我們提到過,哈希碰撞是使用哈希表時(shí)不可避免的一部分,既然 Python 字典是哈希表的實(shí)現(xiàn),所以也需要相應(yīng)的方法來處理哈希碰撞pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

在 Python 的哈希表實(shí)現(xiàn)中,為了避免哈希沖突,通常會(huì)使用開放尋址法的變體之一,稱為“線性探測(cè)”(Linear Probing)pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)在字典中發(fā)生哈希沖突時(shí),Python 會(huì)使用線性探測(cè),即從哈希沖突的位置開始,依次往后查找下一個(gè)可用的插槽(空槽),直到找到一個(gè)空的插槽來存儲(chǔ)要插入的鍵值對(duì)。pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

這種方法簡(jiǎn)單直接,可以減少哈希沖突的次數(shù)。但是,它可能會(huì)導(dǎo)致“聚集”(Clustering)問題,即一旦哈希表中形成了一片連續(xù)的已被占用的位置,新元素可能會(huì)被迫放入這片區(qū)域,導(dǎo)致哈希表性能下降pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

為了緩解聚集問題,假若當(dāng)哈希表中存放的鍵值對(duì)超過哈希表長(zhǎng)度的三分之二時(shí)(即裝載率超過66%時(shí)),哈希表會(huì)自動(dòng)擴(kuò)容pfz28資訊網(wǎng)——每日最新資訊28at.com

pfz28資訊網(wǎng)——每日最新資訊28at.com

最后總結(jié)一下:pfz28資訊網(wǎng)——每日最新資訊28at.com

  • 在哈希表中,是根據(jù)哈希值(即索引)來尋找數(shù)據(jù),所以可以快速定位到數(shù)據(jù)在哈希表中的位置
  • Python 的字典以哈希表的形式運(yùn)行,當(dāng)我們創(chuàng)建字典并添加鍵值對(duì)時(shí),Python 會(huì)將哈希函數(shù)作用于鍵,從而生成哈希值,接著哈希值決定對(duì)應(yīng)的值將存儲(chǔ)在內(nèi)存的哪個(gè)位置中
  • Python 通常會(huì)使用線性探測(cè)法來解決哈希沖突問題

本文鏈接:http://www.www897cc.com/showinfo-26-34685-0.htmlPython 哈希表的實(shí)現(xiàn)——字典

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 十個(gè)殺手級(jí)VS Code插件

下一篇: PHP 8.3 正式發(fā)布!

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 高阳县| 澄城县| 新和县| 河东区| 九寨沟县| 怀来县| 玉环县| 维西| 吕梁市| 甘谷县| 耒阳市| 金湖县| 大姚县| 新乡县| 岚皋县| 临安市| 淄博市| 灌云县| 英超| 井研县| 宁晋县| 延边| 郯城县| 资溪县| 佳木斯市| 襄汾县| 霍邱县| 台南县| 山西省| 蓬安县| 巨野县| 密山市| 广汉市| 镇坪县| 邯郸市| 大竹县| 西昌市| 康平县| 永清县| 兰西县| 徐州市|