c++的set容器怎么用 自动排序和去重的实现【数据结构】


set是基于红黑树实现的自动排序、去重关联容器,插入/查找/删除均为O(log n);默认升序,支持greater或lambda自定义降序;insert返回pair指示是否插入成功,去重依赖等价关系而非相等。

在 C++ 中,set 是一个基于红黑树(Red-Black Tree)实现的关联式容器,它天然支持自动排序元素去重,不需要手动干预。只要把元素插入进去,它就会按升序排列,且重复值只会保留一份。

set 的基本用法和自动排序原理

set 内部使用红黑树组织数据,所有插入、查找、删除操作的时间复杂度都是 O(log n)。红黑树是一种自平衡二叉搜索树,它要求左子树所有节点值小于根,右子树所有节点值大于根——这直接决定了元素插入后自动按升序排列。

  • 默认按 比较:比如 set 插入 {5, 2, 8, 2, 1},最终内容是 {1, 2, 5, 8}
  • 插入重复元素时,insert() 返回一个 pair,其中 secondfalse,表示未插入成功
  • 不能通过下标访问(如 s[0]),只能用迭代器遍历

如何自定义排序规则(比如降序)

如果想让 set 按降序排列,可以传入自定义比较函数对象(仿函数)或 lambda(C++11 起支持):

  • greater set> s; → 从大到小
  • 用 lambda(需配合 decltype 或写成函数对象):实际中更常用的是写结构体或用 std::greater
  • 自定义类型必须提供可比较的 operator

去重是怎么做到的?和 insert 的返回值有关

set::insert() 的返回类型是 pair,其中 bool 表示是否成功插入。内部逻辑是:先查找是否存在相等元素(用 operator== 等价于 !(a),若已存在,就跳过插入。

  • 注意:去重依据是“等价”而非“相等”。对 int 来说效果一样;但对浮点数或自定义类型要小心精度和比较逻辑
  • 没有类似 unordered_set 的哈希机制,所以不依赖 hash==,只依赖严格弱序(strict weak ordering)
  • 不能修改已插入元素的值(因为会破坏红黑树结构),如需更新,应先删后插

常见操作示例(代码片段)

以下是最常用的操作写法:

  • 声明与初始化:set s = {3, 1, 4, 1, 5}; // 自动变成 {1,3,4,5}
  • 插入:s.insert(2); // 成功返回 true
  • 查找:if (s.find(4) != s.end()) { /* 存在 */ }
  • 遍历:for (int x : s) cout
  • 获取大小:s.size() 返回不重复的元素个数


# ai  # c++  # 排列  # red  # if  # for  # 结构体  # bool  # int  # Lambda  # 数据结构  # operator  # 对象  # 自定义  # 子树  # 升序  # 红黑  # 遍历  # 而非  # 降序  # 的是  # 都是  # 是一个 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?  c# 如何用c#实现一个支持优先级的任务队列  Windows 10怎么把任务栏放在屏幕上方_Windows 10解锁任务栏并拖动位置  Windows 11登录时提示“用户配置文件服务登录失败”怎么办_Windows 11修复损坏的用户配置文件  Win11怎么设置开机自动连接宽带_Windows11创建拨号连接计划任务  短链接怎么用php还原_从基础原理到代码实现教学【详解】  Linux如何使用grep搜索文件内容_Linux下正则表达式匹配与查找技巧【指南】  Win11如何设置鼠标灵敏度_Win11鼠标灵敏度调整教程【攻略】  MySQL 中使用 IF 和 CASE 实现查询字段的条件映射  Win11怎么开启移动热点_Windows11共享网络给手机设置教程  Win10路由器怎么隐藏ssid Win10隐藏wifi名称设置【指南】  如何使用Golang benchmark测量函数延迟_统计执行耗时  Mac电脑如何恢复出厂设置_Mac抹掉数据并重装系统【安全指南】  TestNG的testng.xml配置文件怎么写  Win11怎么更改任务栏位置_修改注册表将Win11任务栏置顶【教程】  Windows10如何更改开机密码_Win10登录选项更改密码教程  电脑的“网络和共享中心”去哪了_Windows 11新版网络设置指南【新手】  Windows资源管理器总是卡顿或重启怎么办?(修复方法)  Python函数接口文档化_自动化说明【指导】  php串口通信波特率怎么选_根据硬件手册设置正确波特率【方法】  Linux怎么禁止Root用户远程登录_Linux系统SSH加固与安全设置【教程】  如何在Golang中实现CI/CD流水线自动化测试_Golang持续集成测试执行方法  php8.4如何实现队列任务_php8.4redis队列简单实现方法【教程】  Win10如何卸载自带Edge_Win10彻底卸载Edge浏览器教程【攻略】  Win11怎么开启智能存储_Windows11存储感知自动清理文件  php错误怎么开启_display_errors与log_errors的设置【汇总】  如何在同包不同文件中正确引用 Go 结构体  Win11任务栏怎么放到顶部_Win11修改任务栏位置方法【详细】  如何使用正则表达式提取以编号开头、后跟多个注解的完整代码块  微信短链接怎么还原php_用浏览器开发者工具抓包获取【方法】  Mac怎么安装软件_Mac安装dmg与pkg文件的区别【指南】  Mac怎么设置登录项_Mac管理开机自启动程序【教程】  LINUX怎么进行文本内容搜索_Linux grep命令正则表达式用法大全【教程】  Win11时间格式怎么改成12小时制 Win11时间格式切换教程【步骤】  Win10如何更改开机密码_Windows10登录选项更改密码  如何使用Golang模拟请求超时_Golang context与HTTP请求测试实践  如何在Golang中捕获HTTP服务器错误_GolangHTTP Handler中error处理  如何使用Golang reflect检查方法数量_动态分析类型方法  Windows10如何重置此电脑_Windows10电脑重置方法【步骤】  Win11怎么设置屏保时间_调整Win11屏幕保护等待时间【详解】  Win10系统怎么查看网络连接状态_Windows10网络和共享中心  Win11如何更改用户账户文件夹名称 Win11修改C:Users用户名【终极教程】  Windows10如何更改盘符名称_Win10重命名硬盘分区卷标  php本地部署后session无法保存_session存储路径与权限设置技巧【技巧】  Win11怎么设置快速访问主页_Windows11资源管理器文件夹选项  c++如何实现一个高性能的环形队列(Ring Buffer)_c++无锁实现方法【并发】  Windows怎样拦截WPS弹窗广告_Windows拦截WPS弹窗广告设置【步骤】  Win11怎么更改文件夹图标_自定义Win11文件夹外观样式【详解】  Win10怎样清理C盘浏览器缓存_Win10清理浏览器缓存步骤【步骤】  C++中的std::shared_from_this有什么用?C++安全获取this的shared_ptr【智能指针】 

 2025-12-30

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

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

点击免费数据支持

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

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@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.