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

一文读懂:C++ STL 学生与竞赛选手都会遇到的容器默认排序的疑惑

C++ STL 学生与竞赛选手都会遇到的疑惑。
下面我们系统讲清楚:


🧩 一、结论速览表:STL 常见数据结构默认排序方向

容器类型 默认排序方向 底层实现 比较器默认类型 改为从大到小的写法
std::set 从小到大(升序) 红黑树 std::less<T> std::set<T, std::greater<T>> s;
std::map 从小到大(key 升序) 红黑树 std::less<Key> std::map<Key, Value, std::greater<Key>> m;
std::multiset 从小到大(升序) 红黑树 std::less<T> std::multiset<T, std::greater<T>> ms;
std::priority_queue 从大到小(最大堆) 堆(vector+heap) std::less<T> std::priority_queue<T, vector<T>, std::greater<T>> pq;
std::sort 从小到大(升序) 快速排序 std::less<T> std::sort(a.begin(), a.end(), greater<T>());
std::unordered_set / map 无序(hash) 哈希表 N/A 不支持排序
std::queue / stack 无序 顺序容器封装 N/A 不支持排序

🧠 二、为什么 set 默认是升序,而 priority_queue 默认是降序?

(1)set / map 升序的逻辑:

  • 它们的底层是红黑树(平衡二叉搜索树)
  • 为了保证查找/迭代的逻辑性,默认让中序遍历结果是从小到大。
  • 所以 set<int> s; 中,s.begin() 指向最小值,s.rbegin() 才是最大值。

➡️ 优点:

  • 有序遍历自然是升序;
  • 查找上界 / 下界(upper_bound, lower_bound)逻辑统一。

(2)priority_queue 默认是最大堆(降序输出)的逻辑:

  • 底层是 vector + make_heap / push_heap / pop_heap 实现的二叉堆。
  • 默认比较器 less<T> 表示「大的优先级更高」。
  • 所以 pq.top() 永远返回当前最大元素。

➡️ 优点:

  • 更符合“优先队列”语义:优先取出“最大优先级”元素;
  • 典型应用如 Dijkstra、Huffman、Top-K 问题等。

⚙️ 三、如果要改为从大到小 / 从小到大,怎么写?

✅ 1️⃣ set / map

set<int, greater<int>> s;         // 从大到小
map<int, string, greater<int>> m; // key 从大到小

✅ 2️⃣ priority_queue

默认:

priority_queue<int> pq; // 大根堆(最大值优先)

改为小根堆:

priority_queue<int, vector<int>, greater<int>> pq; // 小根堆(最小值优先)

✅ 3️⃣ sort 排序

sort(v.begin(), v.end());             // 从小到大
sort(v.begin(), v.end(), greater<>());// 从大到小

✅ 4️⃣ multiset

multiset<int, greater<int>> ms; // 从大到小排序

📦 四、举个完整例子:set 与 priority_queue 对比演示

#include <bits/stdc++.h>
using namespace std;int main() {set<int> s1 = {3, 1, 4, 1, 5};set<int, greater<int>> s2 = {3, 1, 4, 1, 5};priority_queue<int> pq1; // 大根堆priority_queue<int, vector<int>, greater<int>> pq2; // 小根堆for (int x : {3, 1, 4, 1, 5}) pq1.push(x), pq2.push(x);cout << "set升序: ";for (int x : s1) cout << x << " ";  // 1 3 4 5cout << "\nset降序: ";for (int x : s2) cout << x << " ";  // 5 4 3 1cout << "\n大根堆: ";while(!pq1.empty()){ cout << pq1.top() << " "; pq1.pop(); } // 5 4 3 1 1cout << "\n小根堆: ";while(!pq2.empty()){ cout << pq2.top() << " "; pq2.pop(); } // 1 1 3 4 5
}

💡 五、总结口诀(记忆法)

容器 默认方向 记忆口诀
set / map 升序 树按中序 → 小到大
priority_queue 降序(最大堆) 优先取“大”的 → 最大堆
sort 升序 从小排到大
改方向 greater<T> 比较器模板换一下就行

记忆技巧

  • 关联容器(set/map):greater<T> 实现从大到小
  • 优先队列greater<T> 实现小根堆(从小到大)
  • 算法函数greater<T>() 实现从大到小排序

记住 greater 总是产生"更严格的"排序规则。

http://www.rkmt.cn/news/20290.html

相关文章:

  • 对数据要求高的On-the-fly
  • 程序设计实践训练(Day1) - --YZ-
  • 【黑马python】基础 4.Python 循环语句 while for range
  • ERP不只是财务软件!如何让生产、采购、仓库都用起来?
  • 2025 年国内智能炒菜机器人厂家最新推荐排行榜:聚焦餐饮降本增效需求,精选行业优质品牌云端/大师/节能/健康炒菜机器人厂家推荐
  • 宝塔项目配置CDN
  • 59. 螺旋矩阵 II 模拟过程
  • AlmaLinux安装Gnome界面
  • setState 第二个参数的作用?
  • 2025 年镀铝板厂商最新推荐榜:聚焦技术创新、行业适配与服务保障的国内优质企业全景解析镀铝板零售/镀铝板零开/镀铝板开平/镀铝板平板厂家推荐
  • 每周读书与学习-初识JMeter 元件(五)
  • 机器学习模型中异常样本、特征的三种常见分类与鉴别方法 - 教程
  • 10-12
  • 20232413邓昊 2025-2026-1 《网络与系统攻防技术》实验一实验报告
  • 充气泵方案:在开发时需要测试那些功能?
  • 直播预告|PostgreSQL 18 六大新特性深度解析
  • 新型电力系统下 MyEMS 微电网协同调度:实践路径与园区落地案例
  • 【华中科大主办|往届EI均检索】第四届声学,流体力学与工程国际学术会议(AFME 2025)
  • 10.13
  • P8037 [COCI2015-2016#7] Prokletnik 题解
  • 【A】The Lost Ship in the Sky
  • 2025 AI 品牌最新推荐排行榜:聚焦商业落地能力,甄选懂需求的实力服务机构东北 Ai/大连 Ai/大连 Ai 培训/大连 Ai 开发/大连 Ai 推广公司推荐
  • 基于经验模态分解的去趋势波动分析(EMD-DFA)方法
  • 双碳目标下企业零碳转型的 MyEMS 碳流可视化支撑体系:路径探索与效能评估
  • 2025 年国内水泵厂家最新推荐排行榜:涵盖多类型水泵,助力用户精准选购优质产品立式多级/自吸/磁力/排污/真空/离心水泵厂家推荐
  • Oracle sql tuning guide 翻译 Part 6-3 --- 用Hint影响优化器 - 指南
  • redhat 链接宝塔mysql报错问题发现到解决
  • vue2初始化过程
  • [Doris/函数] Doris 之数据查询
  • upload的典型案例demo