深入剖析 std::unordered_map 的实现原理之 Hash冲突、退化

本文探讨C++中std::unordered_map的实现原理,包括O(1)时间复杂度的哈希表、哈希冲突的解决方法——开链法,以及如何通过负载因子和Rehash避免哈希表退化,确保操作效率。通过了解这些,可以更好地理解和使用std::unordered_map。
摘要由CSDN通过智能技术生成

本次来讲解下c++中 std::unordered_map的设计原理。

std::unordered_map里面has-a哈希表,它提供的的各个方法基本都是由hashtable封装实现,因此在下文使用hashtable来描述std::unordered_map

  // gnu 实现
  template<typename _Key, 
           typename _Tp,
           typename _Hash  = hash<_Key>,
           typename _Pred  = equal_to<_Key>,
           typename _Alloc = allocator<std::pair<const _Key, _Tp>>>
    class unordered_map
    {
   
      typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc>  _Hashtable;
      _Hashtable _M_h; 	// 内部的唯一成员变量: hashtable
     //...   
    }

O(1)

数组,可以通过索引index在O(1)的时间复杂度内获取元素,但如果不知道index则要O(N)的时间复杂度来查找该节点。hashtable为了弥补这一缺点,采用一个hash函数来计算元素的索引值,来满足O(1)的搜索时间复杂度。其过程如下。

  1. 计算元素的哈希值。对于单个键值对{key, value},计算key对应的哈希值 hashcode = hash_func(key)
  2. 计算元素在数组中的索引值。由于hashcode不一定处于[0, bucket_count]范围内,因此需要将hashcode映射到该范围:index = hashcode % bucket_count

上面两步以O(1)时间复杂度获取了元素在数组中的索引值index,进一步,则能以O(1)时间复杂度给该索引位置赋值或者获取该索引位置的值。两个步骤可实现如下:

size_t bucket_index(const std::unordered_map<int, int>&  map, int key) {
    
    size_t bucket_count   = map.bucket_count();		// map 的桶的个数
    const 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值