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