map、hash_map、unordered_map

基本定义

  1. map底层是用红黑树实现的,查找时间复杂度是O(log(n));
  2. hash_map底层是用hash表存储的,查询时间复杂度是O(1);
  3. unordered_map和hash_map基本一样,只是unordered_map已经加到C++11标准,而hash_map未加入在C++11标准中。
  4. 由于map使用红黑树实现,所以是有序存储的,因此map的key需要定义operator<,而hash_map和unordered_map是基于hash无序存储的,因此只需要重载operator==。

hash_map、unordered_map

1.hash_map基于哈希表,因此数据插入和查找的时间复杂度几乎是常数时间,而代价是消耗比较多的内存。底层实现上,使用一个下标范围比较大的数组来存储元素,形成很多的桶,利用hash函数对key进行映射到不同区域进行保存。

插入操作:使用key通过hash函数得到hash值 -> 得到桶号(hash值对桶数求模) -> 存放key和value在桶内
取值过程:使用key通过hash函数得到hash值 -> 得到桶号(hash值对桶数求模) -> 比较桶内元素与key是否相等 -> 取出相等纪录的value

2.扩容时需要满足两个条件:存放新值的时候当前hash_map所有元素的个数大于等于阈值;存放新值的时候当前存放数据发生hash碰撞。STL会默认指定初始桶大小为16,负载因子是0.75,因此阈值就是16*0.75 = 12,所以当新插入元素时,当前的元素个数超过12,并且发生了冲突,就会扩容hash桶。扩容的大小是给之前的数组翻倍。

3.在hashmap数组扩容之后,原数组中的数据必须重新计算其在新数组中的位置,并放进去,这就是Rehash。 所以如果已经预知hashmap中元素的个数,那么预设元素的个数能够有效的提高hashmap的性能,例如最多有1000个元素,则创建时:new HashMap(2048)(1024是不够的,要考虑负载因子:1024*0.75 = 768)。

4.桶的大小为2的幂次方时,hash_map的效率最高。这是因为:正常的取index方法为hash%length,但是由于位运算比取余快,所以代码中实现为index = hash & (length - 1),所以只有length大小为2的次幂时:hash % length == hash & (length - 1)。

用法

hash_map 查找速度会比map快,属于常数级别;而map的查找速度是log(n)级别。并不一定常数就比log(n)小, 因为hash函数计算也需要耗时。
如果对内存使用特别严格,需要程序尽可能少消耗内存,那么应该是用map,因为hash_map占用内存较多。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值