当前位置: 首页 > news >正文

std::unordered_set(C++)

std::unorderd_set

  • 1. 概述
    • 定义
    • 特点
  • 2. 内部实现
  • 3. 性能特征
  • 4. 常用 API
  • 5. 使用示例
  • 6. 自定义哈希与比较
  • 7. 注意事项与优化
  • 8. 使用建议

1. 概述

定义

template<class Key,class Hash = std::hash<Key>,class KeyEqual = std::equal_to<Key>,class Allocator = std::allocator<Key>
>
class std::unordered_set;

特点

  • 哈希表:基于哈希表实现,平均具有 O(1) 的查找、插入和删除效率。
  • 无序:元素在桶(bucket)中按哈希值分布,不保证遍历顺序。
  • 唯一:集合中不允许重复元素;插入已存在的键,不会改变容器状态。

2. 内部实现

  1. 桶与冲突解决

    • 容器维护若干桶,每个桶内用链表(或单链/双链)存放哈希冲突的元素。
    • 元素落桶位置:bucket_index = hash(key) % bucket_count。
  2. 装载因子(load factor)

    • 定义:load_factor = size() / bucket_count。
    • 达到或超过 max_load_factor() 时,自动 rehash(扩容并重新分布)。
  3. 再哈希(rehash)与保留(reserve)

    • rehash(n):将桶数至少调整为 n,并重分配元素。
    • reserve(n):保证能存放 n 个元素而不触发自动 rehash。

3. 性能特征

操作平均复杂度最坏情况复杂度说明
findO(1)O(n)当所有元素落入同一桶时退化为链表扫描
insertO(1)O(n)可能触发 rehash(O(n))
erase(key)O(1)O(n)同上
clearO(n)O(n)
遍历O(n + b)O(n + b)b = bucket_count;需跳过空桶
  • 空间开销:
    • 每个桶存储一个指针(头结点);每个元素节点存储键值与下一个节点指针。
  • 哈希函数质量:
    • 优质哈希函数能减少冲突,提升最坏情况表现;可针对自定义类型提供专业哈希。

4. 常用 API

// 构造与析构
std::unordered_set<Key> s1;                          // 默认构造
std::unordered_set<Key> s2(100);                     // 指定初始桶数
std::unordered_set<Key> s3(100, MyHash{});           // 指定哈希函数
std::unordered_set<Key> s4(100, MyHash{}, MyEqual{});// 指定哈希与相等比较// 大小与容量
bool empty() const noexcept;
size_t size() const noexcept;
size_t bucket_count() const noexcept;
float load_factor() const noexcept;
float max_load_factor() const noexcept;
void rehash(size_t n);
void reserve(size_t n);// 插入
std::pair<iterator,bool> insert(const Key& key);
template<class... Args>
std::pair<iterator,bool> emplace(Args&&... args);// 查找与删除
iterator find(const Key& key);
size_t erase(const Key& key);
void clear();// 遍历
iterator begin() noexcept;
iterator end() noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;// 桶信息
size_t bucket(const Key& key) const noexcept;
size_t bucket_size(size_t n) const noexcept;
Hash hash_function() const noexcept;
KeyEqual key_eq() const noexcept;

5. 使用示例

#include <unordered_set>
#include <string>
#include <iostream>int main() {// 1. 创建并插入std::unordered_set<std::string> us;us.insert("apple");us.insert(std::string("banana"));us.emplace("cherry");  // 2. 查找if (us.find("banana") != us.end()) {std::cout << "Found banana\n";}// 3. 遍历(无序)for (auto& s : us) {std::cout << s << "\n";}// 4. 预分配桶数us.reserve(1000);  // 预计要插入 1000 个元素,减少 rehash// 5. 输出装载因子std::cout << "Load factor: " << us.load_factor() << "\n";return 0;
}

6. 自定义哈希与比较

对于自定义类型,需提供哈希函数和相等比较:

struct Point { int x, y; };// 自定义哈希:结合位运算
struct PointHash {size_t operator()(Point const& p) const noexcept {return std::hash<int>()(p.x) ^ (std::hash<int>()(p.y) << 1);}
};// 自定义相等比较
struct PointEqual {bool operator()(Point const& a, Point const& b) const noexcept {return a.x == b.x && a.y == b.y;}
};std::unordered_set<Point, PointHash, PointEqual> pts;

7. 注意事项与优化

  1. 避免频繁 rehash

    • 通过 reserve(n) 预先分配,避免多次自动扩容带来的性能抖动。
  2. 遍历顺序不稳定

    • 迭代顺序可能因 rehash 而变化,不要依赖元素插入或桶索引顺序。
  3. 哈希安全

    • 对抗恶意输入可使用带随机种子或高质量哈希(如 MurmurHash、CityHash)。
  4. 线程安全

    • 并发读一般安全;读写或多写需自行加锁。
  5. 内存 vs 性能

    • 哈希表占用内存高于平衡树;在对空间敏感场景须权衡使用。

8. 使用建议

  • 适用场景

    • 快速查找/去重:不关心顺序,关注高效查找/插入/删除时首选。
    • 元素唯一:需要自动去重功能的集合场景。
  • 不适用场景

    • 有序遍历或范围查询:需保序或区间操作时,改用 std::set 或 std::map。
    • 重复键:若允许多值,使用 std::unordered_multiset。

相关文章:

  • 黑马点评:附近商铺+用户签到+UV统计【学习笔记】
  • Spring Boot资源耗尽问题排查与优化
  • Agent的九种设计模式 介绍
  • 基于PySide6与pyCATIA的圆柱体特征生成工具开发实战——NX建模之圆柱命令的参考与移植
  • 在 Babylon.js 中实现智能异步资源加载队列管理
  • React 事件处理基础
  • eNSP无法启动AR报错码40,而且按照eNSP帮助手册排查都没用,我的处理方法【自己存档版】
  • 关于使用webpack构建的vue项目,如何使用windicss
  • 移植的LVGL显示三分之二白屏三分之一灰屏 [正点原子探索者]
  • 53、对 $nextTick异步渲染的理解
  • Selenium 选择器定位元素方式详解
  • AI Agents系列之AI代理架构体系
  • ubuntu 22.04 使用ssh-keygen创建ssh互信账户
  • 基于Atlas 800I A2 + Ubuntu 22.04 LTS 离线部署神州鲲泰问学一体机平台
  • Axure PR 9 中继器 10 编辑行
  • HTTP 核心概念
  • Evidential Deep Learning和证据理论教材的区别(主要是概念)
  • 写论文时降AIGC和降重的一些注意事项
  • 1panel第三方应用商店(本地商店)配置和使用
  • 高防IP如何针对DDoS攻击特点起防护作用
  • 视频丨普京称积极对待任何和平倡议
  • “从山顶到海洋”科技成果科普巡展在重庆启动,免费开放
  • 国际金价冲上3500美元,本月已涨超12%!分析人士提醒:警惕短期多头获利了结
  • 光影连接世界,中国企业出海绘就城市新名片
  • 话剧《门第》将开启全国巡演:聚焦牺牲、爱与付出
  • 服务业扩大开放,金融、医疗等多领域明确155项试点任务