
哈希表在 C++ 中最常用的实现就是 std::unordered_map,它底层基于开放寻址或链地址法(主流实现是**分离链表法**),提供平均 O(1) 的插入、查找和删除。它不是标准强制规定实现方式,但所有主流 STL(如 libstdc++、libc++、MSVC STL)都采用**哈希 + 拉链(bucket + linked list)**结构,配合动态扩容和负载因子控制。
每个桶(bucket)是一个指针,指向一条以哈希值相同元素构成的单向链表。关键成员通常包括:
key、value、next 指针(可能还有 hash 值缓存)load_factor = size / bucket_count
给定 key,流程如下:
std::hash<key>()(key)</key> 得到一个 size_t 类型哈希值(对自定义类型需特化或传 Hash 函数对象)hash_value % bucket_count 算出下标(libstdc++ 实际用更优的 hash_value & (bucket_count - 1),但前提是 bucket_count 是 2 的幂;而实际它用的是质数,所以仍是取模)operator== 比较 key(注意:哈希相等 ≠ key 相等,必须二次判断)插入逻辑简述:
腾讯AI 开放平台
腾讯AI开放平台
381
查看详情
size > max_load_factor * bucket_count,触发 rehash:分配新桶数组(更大质数),把所有旧节点重新 hash 插入新表libstdc++ 中 rehash 会将 bucket_count 设为「不小于指定值的最小质数」,质数表是静态预置的(如 11, 23, 47, 97...)。
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
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。