【面试】标准库相关题型(三)

文章详细介绍了C++中unordered_map的底层实现,包括基于散列表的哈希映射原理,处理哈希碰撞的拉链法,以及负载因子和重新哈希策略。此外,还探讨了迭代器的作用、种类和底层原理,以及在不同容器中的行为。最后,文章提到了STL容器在多线程环境下的线程安全问题,指出容器本身不具备线程安全特性,需要通过加锁等手段保证并发安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. unordered_map底层实现原理

一句话概括:unordered_map 是基于散列表实现的 map。

1.1 散列表

  1. 定义和操作

    散列表是一种数据结构,它通过哈希函数把键(key)映射到哈希表的一个位置,然后在这个位置上存储键值对(key-value pair)。在 C++ 中,哈希表可以通过一个数组和一个哈希函数实现。

    template<typename Key, typename Value>
    class HashTable {
         
        vector<list<pair<Key, Value>>> data;  // 哈希表数据
        // 其他数据成员和函数成员...
    };
    
  2. 哈希碰撞和解决方案

    哈希碰撞是指多个不同的键被哈希函数映射到哈希表的同一个位置。主要有以下三种处理哈希碰撞的方法:

    • 线性探测:当碰撞发生时,向后寻找下一个空位存放数据。
    • 开放寻址:同样是在发生碰撞时向后寻找,但会使用二次哈希等方法改变探测的步长。
    • 拉链法:使用链表处理碰撞,把同一位置的键值对存入一个链表。

    STL 中的 unordered_map 使用的是拉链法处理哈希碰撞。

    // 拉链法的实现示例
    int hashFunc(Key key) {
          /* 哈希函数... */ }
    
    void insert(Key key, Value value) {
         
        int index = hashFunc(key);
        data[index].push_back(make_pair(key, value));  // 在链表尾部添加键值对
    }
    
  3. 负载因子

    负载因子是散列表的实际元素数量和位置数量(桶的数量)的比值。当负载因子过高时,哈希碰撞的概率增加,查询效率降低。

  4. 重新哈希

    当负载因子大于预设阈值(通常为1)时,会发起重新哈希(rehash),即扩大位置数量,并重新分配所有元素。

    void rehash() {
         
        // 创建新的更大的哈希表,把所有元素重新分配到新的哈希表
    }
    

1.2 STL 中的 unordered_map 的实现

  1. 哈希表的模板参数

    unordered_map 采用了复杂的模板参数设计,主要包括键类型 _Key、值类型 _Value、内存分配器 _Alloc、提取键的函数 _ExtractKey、比较键是否相等的函数 _Equal、哈希函数 _H1、映射函数 _H2、调用哈希函数和映射函数的函数 _Hash、重新哈希策略 _RehashPolicy 以及内存相关的 _Traits 等。

  2. 数据成员

    • _M_buckets:哈希表的指针数组,数组的每个元素是一个链表。
    • _M_bucket_count:数组长度,即哈希表的位置数量。
    • _M_element_count:实际存储的元素数量。
    • _M_before_begin:一个特殊的节点,它的下一个节点是哈希表的第一个节点。
    • _M_rehash_policy:重新哈希的策略对象,它决定何时需要重新哈希。
    • _M_single_bucket:一个临时的单节点桶,用于临时存储元素。
  3. 节点定义

    每个节点是一个结构体,包含了键值对的存储空间 _M_storage 和其他需要的信息。

    struct _Hash_node : _Hash_node_base {
         
        __stored_ptr _M_storage;
    };
    
  4. 主要的接口

    unordered_map 主要的接口包括插入、查找、删除等操作,它们的实现都是调用哈希表的对应函数。其中,插入操作 _M_insert_bucket_begin 是先确定插入的位置,然后在这个位置的链表头部插入新的键值对。

1.3 unordered_map

  1. 定义

    unordered_map 是一个模板类,它的模板参数包括键类型、值类型、哈希函数、比较函数和内存分配器。它的主要数据成员是一个 _Hashtable 对象。

    template<typename _Key, typename _Tp, typename _Hash = std::hash<_Key>, typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator<std::pair<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ricky_0528

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值