unordered_map底层原理


C++标准库中,std::unordered_map 的底层实现通常是基于‌哈希表‌,而哈希表的核心结构通常包含一个动态数组(类似于 std::vector)来存储“桶”(buckets)。每个桶内可能用链表或红黑树(C++11后某些实现用)处理哈希冲突。以下是关键点:

1 ‌数据结构‌

底层存储:哈希表需要一个连续的存储空间来管理桶,通常会使用动态数组(如 std::vector 的类似结构)来支持动态扩容。
‌冲突解决‌:每个桶内存储的是链表节点红黑树节点(取决于实现)。
在这里插入图片描述

2 ‌动态扩容机制‌

当哈希表的负载因子(元素数量 / 桶数量)超过阈值(默认为1.0)时,会触发以下操作:

‌分配新数组‌:创建一个更大的动态数组(通常是原大小的两倍左右)。 ‌重新哈希‌:将所有元素重新哈希到新的桶中。
‌释放旧数组‌:销毁旧桶数组。 这个过程与 std::vector 的扩容逻辑类似,但需要重新哈希所有元素。

2.1 为什么用动态数组?‌

‌快速随机访问‌:通过哈希函数计算出的索引需要直接访问对应桶,动态数组的连续内存布局(O(1)时间复杂度)满足这一需求。
‌内存效率‌:动态数组的内存分配比链表更紧凑,缓存局部性更好。

3 一些关键API

  1. 桶大小
std::unordered_map<int, std::string> myMap(100); // 初始桶数量为100
myMap.bucket_count(); // 获取当前桶的数量
  1. 重新哈希

如果你在插入大量元素后发现性能下降,可能是因为当前的桶数量不足以容纳所有元素,从而导致过多的冲突。在这种情况下,你可以通过重新哈希来增加桶的数量。这可以通过调用rehash函数来实现:

myMap.rehash(200); // 尝试将桶数量增加到200
  1. 负载因子
  • unordered_map的负载因子是元素数量与桶数量的比率。当负载因子超过某个阈值(通常是1),unordered_map会自动进行重新哈希以增加桶的数量。

  • 当元素减少使得负载因子降低时,unordered_map不会自动调整桶的数量,此时可以通过调用reserve方法来预估所需的元素数量,这会触发一个合适的重新哈希:

myMap.reserve(1000); // 预计将有1000个元素,这可能导致重新哈希以增加桶的数量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值