STL hash map 底層初探

2021-06-22 23:03:01 字數 1980 閱讀 8622

hash_map 底層是採用hashtable實現的,在講解hash_map之前,先看一下hash_table的原理。

(1)hashtable資料結構

hash table**內的元素稱為桶(bucket),而由桶所鏈結的元素稱為節點(node),其中存入桶元素的容器為stl本身很重要的一種序列式容器——vector容器。之所以選擇vector為存放桶元素的基礎容器,主要是因為vector容器本身具有動態擴容能力,無需人工干預。而節點元素為自定義的結構體:

template

struct __hashtable_node{   

__hashtable_node* next;

value val; };

可以看到,這本身就是一種很典型的鏈式列表元素的表示方法,通過當前節點,我們可以很方便地通過節點自身的next指標來獲取下一鏈結節點元素。如下圖:

(2)hashtable中的迭代器原理:

向前操作:首先嘗試從目前所指的節點出發,前進乙個位置(節點),由於節點被安置於list內,所以利用節點的next指標即可輕易完成前進操作,如果目前正巧是list的尾端,就跳至下乙個bucket身上,那正是指向下乙個list的頭部節點。注意沒有hahtable不存在反向迭代器

如下圖:

從頭到尾迭代器將依次輸出: 53, 55, 2, 108, 59, 63  (和map,set不同,這裡是無序輸出)

(3)hashtable的擴充resize(...)方法:

容此api主要用於判斷當前裝載桶元素的vector容器是否需要重建(或者說是擴

),api的唯一引數即為當前桶元素所鏈結所有節點個數,即鍊錶節點個數(包括當前桶元素),假定為new_num。將new_num值與當前裝載桶元素vector容器的大小進行比較,如果大於則進行容器擴容,依次將所有的節點元素都根據其本身的hash值放置到新的容器對應的桶元素所在的鍊錶中。從上訴演算法中我們可以看到每個桶元素所在的鍊錶的元素個數最多為裝載桶元素的vector容器的容量。。

(4) hash_map

了解了hashtable的原理,我們下面將下hash_map  。 hash_map 的直觀實現如下:

hash_map每個節點中儲存著乙個key, 乙個value 以及指向下乙個節點的指標還有erased位。

(5) map 和hash_map之間的差別

map和hash_map之間最本質的差異就在於:map對其元素型別有乙個

mapm1; // 用< 比較串

mapm2 ; //用自定義的比較串

hash_maphm1; // 用hash()雜湊,用==比較

hash_maphm2; // 用hfct()雜湊,用==比較

hash_maphm3; // 用hfct()雜湊,用eql比較

(6)map和hash_map之間的權衡

map之間的權衡應該是時間和空間的權衡。有效雜湊的關鍵在於雜湊函式的質量。如果無法找到乙個好的雜湊函式,map就容易在效能上超過hash_map. 給予c風格字串、string或者整數的雜湊通常都非常有效。

如果要保持元素的順序性,就選用map而不選用hash_map 如果

如果查詢速度極其重要,就選用hash_map而不是map.

如果無法對元素定義小於操作時,選用hash_map而不是map。

(6)hash_map 使用

參見:

STL hash map 底層初探

hash map 底層是採用hashtable實現的,在講解hash map之前,先看一下hash table的原理。1 hashtable資料結構 hash table 內的元素稱為桶 bucket 而由桶所鏈結的元素稱為節點 node 其中存入桶元素的容器為stl本身很重要的一種序列式容器 ve...

iOS底層原理篇 十七 Block初探

1.block的分類 常見的三種block void viewdidload block nslog block 列印結果 block探析 2300 140310 我是全域性block block探析 2300 140310 nsglobalblock 0x10d14e038 void viewdi...

mysql 底層引擎 mysql底層簡述

mysql 日誌系統 1 redo日誌 基於innodb引擎 redo log通常是物理日誌,記錄的是資料頁的物理修改,而不是某一行或者某幾行的修改,用來恢復提交後的物理資料頁。redo log使用wal write ahead logging 技術,每次提交事務後,都會講儲存引擎中的log buf...