C HashMap原理 與Map的區別

2021-10-08 09:31:30 字數 1678 閱讀 4070

雜湊表最大的優點,就是把資料的儲存和查詢消耗的時間大大降低,幾乎可以看成是常數時間;而代價僅僅是消耗比較多的記憶體。然而在當前可利用記憶體越來越多的情況下,用空間換時間的做法是值得的。另外,編碼比較容易也是它的特點之一。

其基本原理是:使用乙個下標範圍比較大的陣列來儲存元素。可以設計乙個函式(雜湊函式,也叫做雜湊函式),使得每個元素的關鍵字都與乙個函式值(即陣列下標,hash值)相對應,於是用這個陣列單元來儲存這個元素;也可以簡單的理解為,按照關鍵字為每乙個元素「分類」,然後將這個元素儲存在相應「類」所對應的地方,稱為桶。

但是,不能夠保證每個元素的關鍵字與函式值是一一對應的,因此極有可能出現對於不同的元素,卻計算出了相同的函式值,這樣就產生了「衝突」,換句話說,就是把不同的元素分在了相同的「類」之中。 總的來說,「直接定址」與「解決衝突」是雜湊表的兩大特點。

hash_map,首先分配一大片記憶體,形成許多桶。是利用hash函式,對key進行對映到不同區域(桶)進行儲存。其插入過程是:

其取值過程是:

由此可見,要實現雜湊表, 和使用者相關的是:hash函式比較函式。這兩個引數剛好是我們在使用hash_map時需要指定的引數。

hashmap的實現用到了陣列、鍊錶、紅黑樹。

陣列:查詢速度快,可以根據索引查詢;但插入和刪除比較困難;

鍊錶:查詢速度慢,需要遍歷整個鍊錶,但插入和刪除操作比較容易。

hashmap是陣列和鍊錶組成的,資料結構中又叫「鍊錶雜湊」。單線鍊錶如果長度超過8的話會變成紅黑樹。

雜湊衝突的解決辦法

裝填因子 a = 總鍵值對數(下標占用數) /  雜湊表總長度

雜湊表的裝填因子最好控制在0.7-0.8

![說明]( "標題")

![說明]( "標題")

hashmap的擴容並不是為單線鍊錶準備的,單線鍊錶只是為了解決hash衝突準備的。也就是說當陣列達到一定長度,比如說hashmap預設陣列長度是16,那麼達到出發條件,陣列儲存比例達到了75% ,也就是16*0.75=12的時候就會發生擴容

stl的map底層是用紅黑樹實現的,查詢時間複雜度是log(n);

stl的hash_map底層是用hash表儲存的,查詢時間複雜度是o(1);

什麼時候用map,什麼時候用hash_map?

這個要看具體的應用,不一定常數級別的hash_map一定比log(n)級別的map要好,hash_map的hash函式以及解決位址衝突等都要耗時間,而且眾所周知hash表是以空間換時間的,因而hash_map的記憶體消耗肯定要大,一般情況下,如果記錄非常大,考慮hash_map,查詢效率會高很多,如果要考慮記憶體消耗,則要謹慎使用hash_map。非執行緒安全原理說明

1. resize死迴圈

我們都知道hashmap初始容量大小為16,一般來說,當有資料要插入時,都會檢查容量有沒有超過設定的thredhold,如果超過,需要增大hash表的尺寸,但是這樣一來,整個hash表裡的元素都需要被重算一遍。這叫rehash,這個成本相當的大。

2. fail-fast

如果在使用迭代器的過程中有其他執行緒修改了map,那麼將丟擲concurrentmodificationexception,這就是所謂fail-fast策略。

concurrentmodificationexception的原因以及解決措施

map與set的原理及使用

眾所周知c 比c的使用更加靈活是由於c 中有大量的庫函式。今天我們所研究的是其中的map與set。1.set 底層實現是紅黑樹,元素的鍵值是實數 它的特性及用途 可將元素的鍵值value按公升序輸出 防冗餘 用來判斷正誤 set的介面有許多,我們研究比較常用的。如begin end size此類與之...

Map 原理測試

大家都指導hashmap在儲存的時候都是先計算key的hashcode,來決定儲存的位置,然後再將value存在對應的陣列聯表中entry 這裡我就不細說了,都可以參考,特別是第二篇裡面提到鍊錶是為了儲存同乙個hashcode的,這裡我不太贊同這種表達,明明是取模運算下來決定是哪個陣列下標,怎麼能說...

map函式原理

coding utf 8 python 27 xiaodeng map函式 map函式會對乙個序列物件中的每乙個元素應用被傳入的函式,並返回乙個包含了所有函式呼叫結果的乙個列表 map函式原理 counters 1,2,3,4 updated for x in counters print upda...