字典背後是什麼 雜湊表機制

2021-10-02 18:16:23 字數 1920 閱讀 2935

在前面,我們學習了兩種查詢演算法:順序查詢和二分查詢(實際上是一種——順序查詢每個人都會用)。但假如我們是售貨員,客人問我們某件商品的**時,我們可能不想用這兩種演算法去查詢**——即使二分查詢很快。我們希望客人報出商品時,我們立馬能給出乙個對應的**(客人也希望如此)。為了實現我們的想法,我們需要新的工具:雜湊函式。

雜湊函式是將輸入對映到數字的函式。但是,乙個雜湊函式需要滿足一下幾點:

雜湊函式總是將同樣的輸入對映到同樣的數字。

雜湊函式將不同的輸入對映到不同的數字。

雜湊函式知道它可以對映到的數字的範圍。

滿足這三點的雜湊函式就是優秀的雜湊函式,我們可以利用這個工具來實現我們的想法。

我們有了乙個雜湊函式,它將把輸入對映到0,1,2,3,4這幾個數。

我們先構造乙個空陣列。

我們可以繼續這個過程,輸入「栗子」,「士多啤梨」,「貓糧」,然後我們就有了這五種商品的**的陣列!

當顧客來買貓糧時,我們只需要向雜湊函式輸入「貓糧」,然後到雜湊函式給我們的陣列索引處尋找就行了。雜湊函式的機制保證了我們找到的是貓糧的**。

在上面的過程中,我們其實使用了雜湊函式和陣列構建了乙個雜湊表。雜湊表是包含額外邏輯的資料結構——它使用雜湊函式確定元素的儲存位置。

雜湊表是一種十分有用的複雜資料結構,在不同的語言、不同的地方可能被稱為雜湊對映、對映、字典或者關聯陣列。在我們的主題——python中,它被稱為字典——我們已經很熟悉了,其中,雜湊函式的輸入被我們稱為「鍵」,而雜湊函式返回的索引處儲存的值被我們稱為「值」。

(1). 查詢

雜湊表最直觀的功能就是建立對映與查詢,比如實現乙個**簿之類的功能。當我們訪問乙個**的時候,為了避免大海撈針式的查詢,**都會被對映到乙個ip位址。這個被稱為dns解析的過程可以使用雜湊表。

(2).快取

我們先來看看我們如何訪問**:

我們向**的伺服器發出請求,希望訪問乙個頁面

伺服器做某些計算處理,然後將頁面的資料傳送給你

伺服器做這些處理需要時間,而當大量使用者傳送請求時,伺服器可能來不及一下就進行完那麼多的計算——這會導致**變得很慢,使用者可能會因為體驗很差而流失。這時,快取就成為了解決之道。

實際上,使用者有很多行為是重複性質的——比如上乙個**時,我們可能每次都要進行登陸。那麼登陸這種大量進行的操作,我們可以不用每次都讓伺服器去計算一遍。我們可以讓**記住傳送登陸頁面所需的資料,這樣使用者請求登陸時我們直接將資料傳送就可以,而不用讓伺服器計算這些它算過無數次的資料。

這個快取的過程我們可以使用雜湊表進行:

這樣,伺服器的計算量將大大減少,同時,雜湊表的查詢速度也很快——由於我們在其中使用了陣列。

我們在前面要求雜湊函式可以把不同的輸入對映到不同的值。但是,這樣的雜湊函式是十分理想的,但要想找到乙個理想的雜湊函式可能很難,也就是說,雜湊函式並不總是能將不同的鍵對映到陣列的不同位置。我們把這種現象叫做衝突。

既然衝突不可避免,我們在想辦法構建更好的雜湊函式的同時,也應該避免程式因為衝突而發生錯誤。我們採用的解決辦法是使用陣列構建雜湊表的同時加入鍊錶,當發生衝突時,陣列的該位置加入乙個鍊錶用於儲存不同的值。這樣,我們在搜尋的時候先快速查詢到陣列的該位置,再進入鍊錶進行查詢。

當我們採用這種辦法,並且我們的雜湊函式也很好時,我們幾乎沒有損失。但是,如果我們的雜湊函式將太多的值對映到同乙個位置,就會導致該處有乙個很長的鍊錶,這會嚴重影響雜湊表的速度。最糟的情況下,所有元素都被對映到同乙個位置,這樣的雜湊表和煉表沒什麼區別。

裝填因子

裝填因子是用來度量雜湊表中有多少空位置的。它就像字面意思那樣,用雜湊表包含的元素數 / 位置總數來計算。

裝填因子越低,發生衝突的可能性越小,雜湊表的效能也越高。

實際上,不可能等到裝填因子大於1的時候才調整長度——經驗規則是一旦裝填因子大於0.7,就馬上調整雜湊表長度。

良好的雜湊函式

上一部分我們反覆提及了良好的雜湊函式。良好的雜湊函式讓陣列中的值均勻分布,而不是紮起堆來。

字典 與雜湊表 雜湊

python 用雜湊表來實現 dict。雜湊表其實是乙個稀疏陣列 總是有空白元素的陣列稱為稀疏陣列 在一般書中,雜湊表裡的單元通常叫做表元 bucket 在 dict 的雜湊表當中,每個鍵值對都占用乙個表元,每個表元都有兩個部分,乙個是對鍵的引用,乙個是對值的引用。因為每個表元的大小一致,所以可以通...

雜湊值是什麼

雜湊值是什麼 雜湊值就是檔案的身份證,不過比身份證還嚴格。他是根據檔案大小,時間,型別,創作著,機器等計算出來的,很容易就會發生變化,誰也不能預料下乙個號碼是多少,也沒有更改他的軟體。雜湊演算法將任意長度的二進位制值對映為固定長度的較小二進位制值,這個小的二進位制值稱為雜湊值。雜湊值是一段資料唯一且...

hash 雜湊 是什麼

hash,一般翻譯為雜湊 雜湊,或者音譯為雜湊,是把任意長度的輸入 又叫做預對映pre image 通過雜湊演算法變換成固定長度的輸出,該輸出就是雜湊值。這種轉換是一種壓縮對映,也就是,雜湊值的空間通常遠小於輸入的空間。它其實就是乙個演算法,最簡單的演算法就是加減乘除,比方,我設計個數字演算法,輸入...