C++ set怎么去重 C++集合容器自动排序去重原理【数据结构】
发布时间 - 2026-01-31 00:00:00 点击率:次set插入自动去重依赖红黑树的二分查找与等价判断(非相等),要求比较函数满足严格弱序;若自定义类型仅重载operator==而未提供operator
set 插入时自动去重靠的是 std::less 和等价判断
不是靠“查重后再插入”,而是靠红黑树的插入逻辑:每次插入先按排序规则(默认 std::less)做二分查找,若已存在「等价」元素(即既不小于也不大于),就直接丢弃。这里的关键是「等价」≠「相等」——对 int 没区别,但自定义类型若只重载了 operator== 却没适配比较函数,set 仍会插入“看似重复”的元素。
常见错误现象:set 插入两个字段完全相同的对象,结果 size 变成 2。原因往往是只写了 operator==,却没提供 operator 或自定义 Compare 函数对象。
- 必须确保比较函数满足严格弱序(strict weak ordering):反身性、反对称性、传递性、不可比性的传递性
- 不要用
return a.x == b.x && a.y == b.y当operator —— 这不满足严格弱序 - 推荐写法:
return std::tie(a.x, a.y)
为什么 set 不用哈希而用红黑树实现
因为 set 的核心契约是「有序 + 去重」,不是「快查」。红黑树天然支持 O(log n) 插入/删除/查找,且中序遍历即升序;而哈希表(如 unordered_set)虽平均 O(1),但不保证顺序,也无法直接支持 lower_bound、upper_bound 等范围操作。
性能影响明显:如果你只需要去重、不关心顺序,unordered_set 更快;但一旦需要迭代有序、或频繁调用 lower_bound 查找前驱后继,set 是唯一合理选择。
立即学习“C++免费学习笔记(深入)”;
-
set迭代器是双向迭代器,可 ++/--;unordered_set是前向迭代器,只能 ++ -
set::find返回指向有序位置的迭代器;unordered_set::find返回任意位置的迭代器 - 内存占用:红黑树每个节点带颜色和指针,比哈希桶略高,但更稳定(无哈希冲突扩容抖动)
手动触发去重?没必要,但要注意 insert 返回值
set::insert 返回 std::pair,其中 bool 表示是否成功插入(true = 新元素,false = 已存在)。这不是“手动去重”,而是标准协议的一部分,用于判断是否发生实际变更。
容易踩的坑:有人误用 set::emplace_hint 并传错 hint,导致性能退化甚至逻辑错误;还有人把 set 当作临时去重容器,反复构造再清空,其实不如直接用 std::vector + std::sort + std::unique(尤其数据量小或只去重一次时)。
- 大批量插入建议用范围构造:
set,比循环s(v.begin(), v.end()); insert快(内部优化为批量建树) - 若只是临时去重并转回 vector,且不需要中间有序,
unordered_set+vector构造更快 - 别对
set调用std—— 它要求相邻重复,而
::unique
set根本不会存重复
自定义类型去重失败的典型调试路径
当 set 明明该去重却没去,优先检查三件事:
- 确认
MyClass的比较函数是否被正确使用:在set模板参数里显式传入,或确保operator 是 public 且非模板 - 打印插入前后
s.size()和遍历输出,验证是否真没去重,还是你误判了“相同”逻辑(比如浮点数直接比较) - 用
std::is_sorted(s.begin(), s.end(), comp)检查是否真有序——如果返回 false,说明比较函数违反严格弱序,这是根本原因
最隐蔽的问题:比较函数里用了未初始化成员、或依赖外部状态(如全局变量),导致行为不稳定。这种 bug 往往只在特定编译器或优化等级下暴露。
# ai
# c++
# 区别
# 内存占用
# 为什么
# red
# less
# sort
# 全局变量
# bool
# int
# 循环
# 指针
# 数据结构
# public
# operator
# 对象
# bug
# 自定义
# 迭代
# 红黑
# 遍历
# 更快
# 却没
# 没去
# 的是
# 这是
# 升序
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
微信公众帐号开发教程之图文消息全攻略
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
利用python获取某年中每个月的第一天和最后一天
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
JavaScript数据类型有哪些_如何准确判断一个变量的类型
Android中AutoCompleteTextView自动提示
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
如何快速搭建支持数据库操作的智能建站平台?
如何快速生成凡客建站的专业级图册?
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
中国移动官方网站首页入口 中国移动官网网页登录
js实现获取鼠标当前的位置
如何在IIS7中新建站点?详细步骤解析
Laravel如何实现密码重置功能_Laravel密码找回与重置流程
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
如何在搬瓦工VPS快速搭建网站?
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
node.js报错:Cannot find module 'ejs'的解决办法
企业网站制作这些问题要关注
动图在线制作网站有哪些,滑动动图图集怎么做?
宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程
网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?
网站制作价目表怎么做,珍爱网婚介费用多少?
Laravel PHP版本要求一览_Laravel各版本环境要求对照
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制
香港服务器WordPress建站指南:SEO优化与高效部署策略
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言
如何快速打造个性化非模板自助建站?
php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】
如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程
如何在Ubuntu系统下快速搭建WordPress个人网站?
微信小程序 require机制详解及实例代码
Laravel如何使用withoutEvents方法临时禁用模型事件
SQL查询语句优化的实用方法总结
php 三元运算符实例详细介绍
微信推文制作网站有哪些,怎么做微信推文,急?
Laravel用户密码怎么加密_Laravel Hash门面使用教程
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
微信小程序 wx.uploadFile无法上传解决办法
微信小程序 HTTPS报错整理常见问题及解决方案
Laravel如何创建自定义中间件?(Middleware代码示例)
Laravel如何实现模型的全局作用域?(Global Scope示例)
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
ChatGPT 4.0官网入口地址 ChatGPT在线体验官网


