index = hashcode % n;
int index= h &
(length-1)
;//例如:15%4=3 ==>15&3=1111&0011=0011=3
原理:從二進位制角度來看,x/2 ^n 相當於x>>n,就是把x後移n位,被移掉的部分,則是 x % 2 ^n,所以x%2 ^n就是要獲取後n位。
為了保證陣列大小是2 ^n,計算超過 capacity 的最小 2 ^n:
int
getsize
(int capacity)
return size;
}
這種方法的好處是效率比普通計算高,而且可以使結果均勻散裂,減少雜湊碰撞。
由於相同索引的值不一定只有乙個,所以需要解決位址衝突,其實這個是雜湊表的核心問題:
最經典的方式就是鏈位址法,將相同索引的值,通過拉鍊法掛在hash[index]後。
儲存資料有兩種方式:陣列和鍊錶。陣列的特點是:定址容易,插入和刪除困難;而鍊錶的特點是:定址困難,插入和刪除容易。上面提到的鏈位址法,其實就是將陣列和鍊錶組合在一起,發揮了兩者的優勢,我們可以將其理解為鍊錶的陣列。
同時,當鍊表長度hashmap還有紅黑樹,為了實現比此時鍊錶更高效的查詢。但是紅黑樹的出現是有要求的,要求鍊錶長度》8,並且陣列長度》64。如果陣列長度沒有超過64則在衝突時首先採用擴容的方法。擴容時,負載因子會確定在它沒滿之前的負載量,達到就擴容,最大容量是2^30。擴容後要rehash,把雜湊值對映到新的雜湊值中。雜湊值只會於原位置或者是原位置+舊容量(二進位制的第一位決定,是1的話則擴容那一位與運算會生效)。
因為每個空間中的節點的數量分布服從泊松分布,8的時候幾乎沒有,自動轉為樹(不想讓你轉為樹,因為樹節點記憶體大),是時間與空間的權衡。
雜湊衝突的原因:高位不同、低位相同,導致雜湊很多。讓低位和高位結合在一起看,使任何一位發生變化都能影響到最後的index值。
hashmap想了一種辦法(擾動):將hash值的高16位右移並與原hash值取異或運算(^),混合高16位和低16位的值,得到乙個更加雜湊的低16位的hash值。再通過雜湊函式找到它的index值,如:
// 沒有hash碰撞
h1 = h1 ^
(h1 >>
>16)
=5;h2 = h2 ^
(h2 >>
>16)
=250
;index1 =(2
^n -1)
& h1 =5&
15=5index2 =(2
^n -1)
& h2 =
250&15=
10
還有辦法嘛?
開放位址法:要是發生衝突就往後乙個,直到找到乙個空位。
再雜湊法:用另外乙個雜湊函式找到另外乙個key值。
建立公共溢區
思路:定義資料結構:priority_queue,unordered_map,vector;
1.定義hashmap用來儲存value和對應的頻率,即
unordered_map int,
int>>
;
2.按照頻率排序,放入優先佇列中(即堆排序);
3.取優先佇列中,頻率前k個的對應值;
**:
vector<
int>
topkfrequent
(vector<
int>
& nums,
int k);}
unordered_map<
int,
int> map;
//定義hashmap(容器)
for(
auto i:nums)
priority_queueint,
int>
,vectorint,
int>>
,greaterint,
int>>
> que;
//定義乙個小頂堆(優先佇列預設是大頂堆)
/*struct cmp
}while
(que.
size()
>0)
return vector<
int>
(res.
rbegin()
,res.
rend()
);//由於是小頂堆,結果應為逆序
}
時間複雜度: HashMap以及跟HashMap相關的內容
hashmap相信大家都用過,是以這樣的格式儲存的。其實內部真正用於儲存的是entry的陣列table 桶 下面就是源 了已經標註出來了 emprty table是個空表,用於是初始化時使用的。default load factor是負載因子,default initial capacity是初始化...
HASHMAP解決hash碰撞相關問題
1.封裝類作為key,都是final型別保證hash值不可更改 內部已經實現equals和hashcode方法,遵循hashmap內部規範計算準確性,有效減少hash碰撞的機率,2.如果使用object作為key,需要重寫equals和hashcode方法,equals保證key在hash表中唯一,...
HashMap的remove相關方法
前面增加和查詢都解析完了,這裡我們看一下跟刪除相關的方法。public v remove object key 通過原始碼可以看到,主要的功能方法還是裡面的removenode方法,我們看一下removenode方法 final node removenode int hash,object key...