W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
key
? ,哈希表能夠在 O(1) 時間內(nèi)查詢到 ?value
? ,效率非常高。key
? 映射為數(shù)組索引,從而訪問對應(yīng)桶并獲取 ?value
? 。key
? 可能在經(jīng)過哈希函數(shù)后得到相同的數(shù)組索引,導(dǎo)致查詢結(jié)果出錯,這種現(xiàn)象被稱為哈希沖突。HashMap
? 使用鏈式地址,而 Python 的 ?Dict
? 采用開放尋址。哈希表的時間復(fù)雜度為什么不是 O(n) ?
當(dāng)哈希沖突比較嚴重時,哈希表的時間復(fù)雜度會退化至 O(n) 。當(dāng)哈希函數(shù)設(shè)計的比較好、容量設(shè)置比較合理、沖突比較平均時,時間復(fù)雜度是 O(1) 。我們使用編程語言內(nèi)置的哈希表時,通常認為時間復(fù)雜度是 O(1) 。
為什么不使用哈希函數(shù) f(x)=x 呢?這樣就不會有沖突了
在 f(x)=x 哈希函數(shù)下,每個元素對應(yīng)唯一的桶索引,這與數(shù)組等價。然而,輸入空間通常遠大于輸出空間(數(shù)組長度),因此哈希函數(shù)的最后一步往往是對數(shù)組長度取模。換句話說,哈希表的目標是將一個較大的狀態(tài)空間映射到一個較小的空間,并提供 O(1) 的查詢效率。
哈希表底層實現(xiàn)是數(shù)組、鏈表、二叉樹,但為什么效率可以比他們更高呢?
首先,哈希表的時間效率變高,但空間效率變低了。哈希表有相當(dāng)一部分的內(nèi)存是未使用的,
其次,只是在特定使用場景下時間效率變高了。如果一個功能能夠在相同的時間復(fù)雜度下使用數(shù)組或鏈表實現(xiàn),那么通常比哈希表更快。這是因為哈希函數(shù)計算需要開銷,時間復(fù)雜度的常數(shù)項更大。
最后,哈希表的時間復(fù)雜度可能發(fā)生劣化。例如在鏈式地址中,我們采取在鏈表或紅黑樹中執(zhí)行查找操作,仍然有退化至 O(n) 時間的風(fēng)險。
多次哈希有不能直接刪除元素的缺陷嗎?對于標記已刪除的空間,這個空間還能再次使用嗎?
多次哈希是開放尋址的一種,開放尋址法都有不能直接刪除元素的缺陷,需要通過標記刪除。被標記為已刪除的空間是可以再次被使用的。當(dāng)將新元素插入哈希表,并且通過哈希函數(shù)找到了被標記為已刪除的位置時,該位置可以被新的元素使用。這樣做既能保持哈希表的探測序列不變,又能保證哈希表的空間使用率。
為什么在線性探測中,查找元素的時候會出現(xiàn)哈希沖突呢?
查找的時候通過哈希函數(shù)找到對應(yīng)的桶和鍵值對,發(fā)現(xiàn) ?key
? 不匹配,這就代表有哈希沖突。因此,線性探測法會根據(jù)預(yù)先設(shè)定的步長依次向下查找,直至找到正確的鍵值對或無法找到跳出為止。
為什么哈希表擴容能夠緩解哈希沖突?
哈希函數(shù)的最后一步往往是對數(shù)組長度 n 取余,讓輸出值落入在數(shù)組索引范圍;在擴容后,數(shù)組長度 n 發(fā)生變化,而 ?key
? 對應(yīng)的索引也可能發(fā)生變化。原先落在同一個桶的多個 ?key
? ,在擴容后可能會被分配到多個桶中,從而實現(xiàn)哈希沖突的緩解。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: