c++如何实现一个哈希表_c++数据结构unordered_map原理【源码】


c++kquote>std::unordered_map底层采用哈希+拉链法,以质数大小的桶数组和单向链表节点构成,通过哈希值取模定位bucket,负载因子超限触发rehash。

c++如何实现一个哈希表_c++数据结构unordered_map原理【源码】

哈希表在 C++ 中最常用的实现就是 std::unordered_map,它底层基于开放寻址或链地址法(主流实现是**分离链表法**),提供平均 O(1) 的插入、查找和删除。它不是标准强制规定实现方式,但所有主流 STL(如 libstdc++、libc++、MSVC STL)都采用**哈希 + 拉链(bucket + linked list)**结构,配合动态扩容和负载因子控制。

核心结构:桶数组 + 单向链表节点

每个桶(bucket)是一个指针,指向一条以哈希值相同元素构成的单向链表。关键成员通常包括:

  • bucket 数组(vector:大小为质数(避免哈希冲突聚集),初始一般为 11 或 17
  • Node 结构:含 keyvaluenext 指针(可能还有 hash 值缓存)
  • 元素总数(size)和桶数量(bucket_count):用于计算负载因子 load_factor = size / bucket_count
  • 最大负载因子(max_load_factor):默认 1.0,超限触发 rehash

哈希与映射:如何定位 bucket

给定 key,流程如下:

  • 调用 std::hash<key>()(key)</key> 得到一个 size_t 类型哈希值(对自定义类型需特化或传 Hash 函数对象)
  • hash_value % bucket_count 算出下标(libstdc++ 实际用更优的 hash_value & (bucket_count - 1),但前提是 bucket_count 是 2 的幂;而实际它用的是质数,所以仍是取模)
  • 遍历该 bucket 对应链表,用 operator== 比较 key(注意:哈希相等 ≠ key 相等,必须二次判断)

插入与扩容:rehash 是性能关键

插入逻辑简述:

腾讯AI 开放平台 腾讯AI 开放平台

腾讯AI开放平台

腾讯AI 开放平台 381 查看详情 腾讯AI 开放平台
  • 计算 bucket 下标
  • 遍历链表检查 key 是否已存在(存在则更新 value)
  • 不存在则 new Node 插入链表头(或尾,取决于实现),size++
  • size > max_load_factor * bucket_count,触发 rehash:分配新桶数组(更大质数),把所有旧节点重新 hash 插入新表

libstdc++ 中 rehash 会将 bucket_count 设为「不小于指定值的最小质数」,质数表是静态预置的(如 11, 23, 47, 97...)。

简易手写版(简化链地址法)示意

(仅演示核心逻辑,无异常/allocator/迭代器等完整功能)

template <typename K, typename V, typename Hash = std::hash<K>, typename Eq = std::equal_to<K>>
class simple_unordered_map {
    struct Node { K key; V value; Node* next; Node(const K& k, const V& v) : key(k), value(v), next(nullptr) {} };
    std::vector<Node*> buckets;
    size_t _size = 0;
    float max_load = 1.0f;
    Hash hasher;
    Eq equal;
<pre class="brush:php;toolbar:false;">size_t hash_index(const K& k) const { return hasher(k) % buckets.size(); }

void rehash(size_t new_bucket_count) {
    std::vector<Node*> new_buckets(new_bucket_count, nullptr);
    for (Node* node : buckets) {
        while (node) {
            Node* next = node->next;
            size_t idx = hasher(node->key) % new_bucket_count;
            node->next = new_buckets[idx];
            new_buckets[idx] = node;
            node = next;
        }
    }
    buckets.swap(new_buckets);
}

public: simple_unordered_map() { buckets.resize(11, nullptr); }

V& operator[](const K& k) {
    size_t idx = hash_index(k);
    Node*& head = buckets[idx];
    for (Node* p = head; p; p = p->next) {
        if (equal(p->key, k)) return p->value;
    }
    // 未找到,插入新节点(头插)
    Node* newNode = new Node(k, V{});
    newNode->next = head;
    buckets[idx] = newNode;
    ++_size;
    if (_size > max_load * buckets.size()) rehash(/*下一个质数*/);
    return buckets[idx]->value;
}

~simple_unordered_map() {
    for (Node* head : buckets) {
        while (head) {
            Node* next = head->next;
            delete head;
            head = next;
        }
    }
}

};

基本上就这些。真正工业级实现(如 GCC 的 libstdc++/include/bits/hashtable.h)还涉及内存池、移动语义、迭代器失效规则、const_iterator 支持、emplace 优化等,但骨架一致:哈希分桶 + 链表容错 + 动态扩容。理解这个模型,读源码就不容易迷失在模板嵌套里。

以上就是c++++如何实现一个哈希表_c++数据结构unordered_map原理【源码】的详细内容,更多请关注其它相关文章!


# 特化  # 老干妈营销推广花费  # 泉山区移动网站建设费用  # 呈贡区网站建设推广公司  # 开花店怎么营销推广  # 服装网站推广计划书  # seo 日均IP和流量  # seo寄生虫使用教程  # 西湖公众号营销推广方案  # 无锡网站推广服务价钱  # 本溪网络推广网站  # 迭代  # node  # 是一个  # 的是  # 如何使用  # 遍历  # 如何实现  # 数据结构  # 链表  # 腾讯  # red  # 质数  # c++ 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: Win10锁屏时间怎么设置 Win10调整自动锁屏时间方法  sublime如何配置PHP开发环境_在sublime中运行与调试PHP代码  12306售票时间最新规定 | 网上订票和车站窗口时间一样吗  12306夜间购票失败? | 查看官方公布的暂停服务公告与应对方案  《偃武》甘宁技能详解  yy漫画登录页面官方入口_yy漫画在线阅读网址入口  Dagster资产间数据传递与用户配置管理教程  火狐浏览器如何刷新修复浏览器 火狐浏览器“重置Firefox”功能详解  realme 10 Pro息屏方案_realme 10 Pro省电策略  AO3中文版手机快速通道_AO3最新稳定链接更新  京东快递包裹信息查询入口 京东快递官方查询平台入口  word文档行距怎么调?word文档调行距的操作步骤  《梦想世界:长风问剑录》药师一图流分享  使用Google服务账号实现Google Drive API无缝集成与文件访问  原子笔记app误删找回教程  在Django单元测试中优雅处理信号:基于环境的条件执行策略  《七读免费小说》开通会员方法  《大润发优鲜》充值方法介绍  如何自定义苹果手机铃声  电脑从睡眠中被自动唤醒怎么办_Windows唤醒源事件查看与禁用【解决】  《爱笔思画x》涂色教程  4399小游戏下装链接 4399小游戏下载链接入口  《全民k歌》音乐怎么下载到本地2025  sublime怎么快速在浏览器中预览HTML_sublime配置View in Browser教程  大熊猫抓取竹子的“大拇指”其实是什么?蚂蚁庄园课堂今天答案最新11月30日  抖音网页版地址直接进入_抖音网页版在线观看入口  顺丰速运官网查询入口 顺丰物流查询官网入口链接  《土豆雅思》修改密码方法  偃武诸葛亮阵容搭配推荐  快手缓存清理方法  抖音官网入口快速访问 抖音网页版账号注册解析  猫眼app抢票快还是小程序快  LINUX怎么查看显卡信息_LINUX查看GPU状态  豆包AI怎样为教育场景定制答疑逻辑_为教育场景定制豆包AI答疑逻辑方案【方案】  Python定时发送QQ消息  哔哩哔哩的|直播|间怎么送礼物_哔哩哔哩|直播|送礼操作指南  风神瞳获取全攻略  《漫蛙manwa2》防走失网页版链接2025  在VS Code中进行数据科学和机器学习开发  b站网页版入口 哔哩哔哩官方网站直接进入  如何使用 composer 和 aop-php 实现 AOP 编程?  word文档中的分隔符有哪些不同类型和用途_Word分隔符类型与用途方法  CSS过渡如何实现按钮悬停效果_transition属性控制背景颜色变化  天堂漫画网页版在线阅读 天堂漫画手机版入口  Yandex世界探索 最新官方免登录入口全知道  PHP安全加载非公开目录图片与动态内容类型处理指南  《深林》冬季章节图文攻略  向往的生活小游戏启动处_向往的生活小游戏立即启动  跨语言测试实践:使用Python Selenium测试现有J*a Web项目  怎样让Windows 11的开始菜单恢复经典样式_Open-Shell工具使用指南【怀旧】 

 2025-12-09

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.