图解算法学习笔记(五):散列表
目錄
1)示例1:
2)散列函數(shù)
3)應(yīng)用案例
4)沖突
5)性能
6)小結(jié)
本章內(nèi)容:
? ? ? ?學(xué)習(xí)散列表,最有用的數(shù)據(jù)結(jié)構(gòu)之一。
? ? ? ?學(xué)習(xí)散列表的內(nèi)部機(jī)制:實(shí)現(xiàn)、沖突和散列函數(shù)。
1)示例1:
假設(shè)你在一家雜貨店上班,有顧客來(lái)買東西時(shí),你得在本子中查找價(jià)格。第一章介紹的簡(jiǎn)單查找,需要O(n)時(shí)間,如果你使用的是二分查找,時(shí)間為O(log n)。
二分查找的速度已經(jīng)很快了,但作為收銀員,在本子中查找價(jià)格是件很痛苦的事,即使本子的內(nèi)容是有序的。在查找價(jià)格時(shí),你都能感覺(jué)到顧客的怒氣。但如果我們有一位雇員(Maggie),她能記住所有商品的價(jià)格,問(wèn)她就能馬上知道答案。這位雇員報(bào)出任何商品的價(jià)格的時(shí)間為O(1)。
2)散列函數(shù)
散列函數(shù)是這樣的函數(shù),無(wú)論你給它什么樣的數(shù)據(jù),它都還給你一個(gè)數(shù)字。
你可能認(rèn)為散列函數(shù)輸出的數(shù)字沒(méi)什么規(guī)律,但其實(shí)散列函數(shù)必須滿足一些要求。
- 它必須是一致的,輸出與輸入保持一致;
- 它應(yīng)將不同的輸入映射到不同的數(shù)字;
現(xiàn)在,我們可以打造我們的"Maggie"了。
首先創(chuàng)建一個(gè)空數(shù)組:
現(xiàn)在,我們將蘋果的價(jià)格加入到數(shù)組中,輸入為apple時(shí),散列函數(shù)的輸入為3,因此我們將蘋果的價(jià)格存儲(chǔ)到數(shù)組的索引3處。
不斷地重復(fù)這個(gè)過(guò)程,最終整個(gè)數(shù)組將填滿價(jià)格。
現(xiàn)在假設(shè)需要知道鱷梨(avocado)的價(jià)格,你無(wú)需在數(shù)組中查找,只需將avocado作為輸入交給散列函數(shù)。,它會(huì)告訴你價(jià)格存儲(chǔ)在索引4處。
散列函數(shù)之所以能準(zhǔn)確地指出價(jià)格的存儲(chǔ)位置,具體原因如下:
- 散列函數(shù)總是將同樣的輸入映射到相同的索引。
- 散列函數(shù)將不同的輸入映射到不同的索引。
- 散列函數(shù)知道數(shù)組有多大,只返回有效的索引。
現(xiàn)在,我們可以結(jié)合散列函數(shù)和數(shù)組創(chuàng)建一個(gè)被稱為散列表(hash table)的數(shù)據(jù)結(jié)構(gòu),在學(xué)習(xí)的復(fù)雜數(shù)據(jù)結(jié)構(gòu)中,散列表可能是最有用的。Python提供的散列表實(shí)現(xiàn)為字典。
3)應(yīng)用案例
散列表用途廣泛,具體有:
- 手機(jī)里的電話簿,DNS解析;
- 防止重復(fù);
- 將散列表用作緩存,緩存是一種常用的加速方式,所有的大型網(wǎng)站都使用緩存,緩存的數(shù)據(jù)存儲(chǔ)在散列表中;
4)沖突
要明白散列表的性能,我們先搞清什么是沖突,現(xiàn)在我們有一個(gè)數(shù)組,它包含26個(gè)位置。
使用的散列函數(shù)非常簡(jiǎn)單,它按字母表順序分配數(shù)組的位置。
現(xiàn)在,我們分別將蘋果,香蕉、鱷梨的價(jià)格存儲(chǔ)到散列表中,會(huì)出現(xiàn)下面這種情況:
這時(shí)出現(xiàn)了沖突(collision):給兩個(gè)鍵分配的位置相同。
最簡(jiǎn)單的辦法如下:如果兩個(gè)鍵映射到同一個(gè)位置,就在這個(gè)位置存儲(chǔ)一個(gè)鏈表。
通過(guò)上面的介紹,我們了解到散列函數(shù)很重要,理想的是散列函數(shù)將鍵均勻地映射到散列表的不同位置。
5)性能
散列表查找、插入、刪除的運(yùn)行時(shí)間如圖所示:
在使用散列表是,避免最糟情況至關(guān)重要,為此,需要避免沖突,需要有:較低的填裝因子,良好的散列函數(shù)。
填裝因子度量的是散列表有多少位置是空的。一個(gè)經(jīng)驗(yàn)是:一旦填裝因子大于0.7,就調(diào)整散列表的長(zhǎng)度。而什么是良好的散列函數(shù),這不需要我們操心——天塌下來(lái)有高個(gè)子頂著。
6)小結(jié)
沖突很糟糕,你應(yīng)使用可以最大限度減少?zèng)_突的散列函數(shù)。
散列表的查找、插入和刪除速度都非常快。
散列表適合用于模擬映射關(guān)系。
一旦填裝因子超過(guò)0.7,就該調(diào)整散列表的長(zhǎng)度。
散列表可用于緩存數(shù)據(jù)(例如,在Web服務(wù)器上)。
散列表非常適合用于防止重復(fù)。
總結(jié)
以上是生活随笔為你收集整理的图解算法学习笔记(五):散列表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 理财产品的产品要素有哪一些?理财产品的类
- 下一篇: Apollo进阶课程 ⑮丨Apollo自