尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
【C++】 priority_queue知识点总结
一、基础概念priority_queue叫优先队列底层不是队列是堆大顶堆 / 小顶堆属于容器适配器。适配器不自己实现底层存储复用别的容器vector/deque做底层只在外层封装堆操作。 队列先进先出优先队列优先级最高的元素先出和入队顺序无关。头文件#include queue// STL原型 template class T, class Container vectorT, class Compare lessT class priority_queue;三个模板参数T存储元素类型Container底层容器默认vectorT要求支持[]、push_back、pop_backCompare仿函数二元谓词默认lessT决定优先级规则⚠️ 最重要规则和你手写仿函数完全一致comp(a,b)返回 true →a 的优先级低于 bb 要排在 a 前面大顶堆要求父节点应该大于等于子节点当子节点 父节点的时候才交换。默认传小于Less仿函数大的优先级高传大于Greater仿函数小的优先级高二、默认大顶堆原理priority_queueint默认priority_queueint, vectorint, lessintlessintcomp(a,b)a bcomp(parent, child)→parent child返回 true父优先级 子子上浮堆顶是最大元素→大顶堆小顶堆写法priority_queueint, vectorint, greaterint minHeap;greaterintcomp(a,b)a b堆顶是最小元素。面试高频坑less→ 大顶堆greater→ 小顶堆很多人记反三、底层堆原理二叉堆完全二叉树数组存储用数组映射完全二叉树父节点下标parent左孩子2*parent 1右孩子2*parent 2子节点找父(child - 1)/2整数除法向下取整堆的两个核心操作向上调整 adjust_up插入 push新元素插在数组末尾不断和父节点比较如果子优先级更高交换父子直到不满足条件 / 到根。对应 pushpush_backadjust_up(最后一个下标)向下调整 adjust_down删除 pop堆顶和末尾元素交换pop_back删掉堆顶新堆顶向下不断和优先级更高的孩子交换直到满足堆性质。对应 pop首尾 swap pop_back adjust_down (0)建堆迭代器区间构造从最后一个非叶子节点开始向前依次向下调整。 最后一个非叶子节点下标(n-2)/2时间复杂度O (n)不是 O (nlogn)插入单个元素O (logn)删除堆顶O (logn)建堆O (n)四、priority_queue 常用接口接口作用注意事项push(x)插入元素自动调整堆底层 push_back 向上调整pop()删除堆顶优先级最高元素不返回堆顶元素空队列调用 UBtop()获取堆顶元素的引用空队列调用 UBconst 引用empty()判空boolsize()返回元素个数size_tqueue 的 front () 返回队首并 pop 分开priority_queuepop()只删不取top()只取不删。#include queue int main() { priority_queueint max_pq; //大顶堆 max_pq.push(1); max_pq.push(9); max_pq.push(5); while(!max_pq.empty()) { cout max_pq.top() ; max_pq.pop(); } //输出9 5 1 return 0; }五、仿函数 Compare 深度理解Compare comp是二元谓词仿函数comp(a,b)返回 boolcomp(a,b) true a 优先级低于 bb 应该放在 a 上方堆中 b 优先级更高// lessT bool operator()(const T a,const T b) { return a b; }comp(p,c)→p c→ true父 p 优先级低于子 c → 交换上浮大顶堆。// greaterT bool operator()(const T a,const T b) { return a b; }comp(p,c)→pc→ true父 p 优先级低于子 c → 交换上浮小顶堆。记忆口诀less是拿比较大顶堆greater拿比较小顶堆六、容器适配器一、什么是容器适配器容器适配器Container Adapter本身不是独立容器它是对已有容器的封装。适配器不自己开辟内存、不实现底层存储复用底层容器的已有接口对外只暴露一套新的、简化的接口改变容器的行为。一句话理解适配器 套壳包装。底层容器负责存数据适配器只提供特定访问规则。一句话理解适配器 套壳包装。底层容器负责存数据适配器只提供特定访问规则。STL 一共 3 个容器适配器stack栈后进先出 LIFOqueue队列先进先出 FIFOpriority_queue优先队列优先级最高元素先出堆适配器默认底层容器底层容器要求stackdequeT支持push_back/pop_back/back()queuedequeT支持push_back/pop_front/back()/front()priority_queuevectorT支持随机访问[]、push_back、pop_back堆算法需要随机下标访问适配器只是限制接口不会新增存储能力。二、三大适配器模板原型1. stacktemplate class T, class Container dequeT class stack;对外接口push()、pop()、top()、empty()、size()只能在尾部操作入栈、出栈、取栈顶不能遍历、不能访问中间元素2. queuetemplate class T, class Container dequeT class queue;对外接口push()、pop()、front()、back()、empty()、size()尾插、头删只能取队首队尾不能遍历中间元素3. priority_queuetemplate class T, class Container vectorT, class Compare lessT class priority_queue;对外接口push()、pop()、top()、empty()、size()只允许取堆顶push/pop 内部自动做堆调整。三、底层容器更换规则适配器可以手动更换底层容器但必须满足接口要求stack底层可以用deque/vector/list只要支持尾插尾删、back ()stackint, vectorint st;queue底层不能用 vector queue 需要头删pop_front()vector 的头删效率极低而且 STL 不允许 vector 作为 queue 底层。 可选deque、listqueueint, listint q;priority_queue必须支持随机访问 []堆调整需要按下标找父子节点 ✅ 允许vector、deque❌ 禁止list没有随机访问priority_queueint, dequeint pq;面试题为什么 priority_queue 默认是 vectorstack/queue 默认 deque 答vector 连续内存随机访问快最适合堆的下标操作deque 头尾增删都是 O (1)不需要移动大量元素适合 stack、queue。四、适配器的共性特点没有迭代器不能遍历适配器刻意隐藏底层容器迭代器。stack/queue/priority_queue 不提供 begin () /end ()。设计目的强制遵守数据结构规则。栈就只能栈顶操作队列只能头尾操作禁止乱序遍历。 如果你拿到迭代器就可以随便修改中间元素破坏栈 / 队列 / 堆的性质。底层容器是适配器的成员就像你手写 priority_queue 里面Container _con;所有操作都是调用_con的成员函数。五、适配器对比表表格特性stackqueuepriority_queue规则LIFO 后进先出FIFO 先进先出按优先级出队默认底层dequedequevector插入位置尾部 push_back尾部 push_back尾部 push_back 向上堆调整删除位置尾部 pop_back头部 pop_front首尾交换 pop_back 向下堆调整取元素top () 栈顶front () 队首 back () 队尾top () 堆顶迭代器❌无❌无❌无模板参数T, ContainerT, ContainerT, Container, Compare 仿函数七、仿函数仿函数本质重载了operator()的类 / 结构体对象可以像函数一样去调用。也叫函数对象。1. 核心原理普通函数调用func(a,b)仿函数调用obj(a,b)看着像函数调用实际是调用这个对象里重载的operator()templateclass T class Less { public: bool operator()(const T x, const T y) { return x y; } };Lessint是类Lessint()是临时对象匿名仿函数com(a,b)等价com.operator()(a,b)Lessint lessObj; // 创建仿函数对象 cout lessObj(2,5); // 等价 lessObj.operator()(2,5)返回 true2. 仿函数 vs 普通函数表格仿函数类重载 operator ()普通函数状态可以保存成员变量携带状态不能存状态模板容易和 STL 算法配合类型推导友好函数指针类型推导麻烦内联编译器更容易内联效率高容易退化成函数调用写的Less/Greater就是 STL 风格的谓词仿函数返回 bool两个参数 → 二元谓词3. 二元谓词规则com(x,y)返回true的含义x 应该排在 y 的后面y 优先级更高y 放前面Lessint com; com(x,y) → x y 返回true // 含义x比y小x优先级更低y更大y要放到前面 → 降序排序Greaterint com; com(x,y) → x y 返回true // 含义x比y大x优先级更低y更小y放到前面 → 升序排序4. 仿函数两种使用方式方式 1匿名临时对象你 main 里用的BubbleSort(a,7, Lessint()); // Lessint() 创建一个临时对象传给模板参数Compare方式 2先定义对象再传入Lessint lessObj; BubbleSort(a,7, lessObj);5. 仿函数可以带状态举个例子统计比较次数templateclass T class LessCount { public: int count 0; bool operator()(const T x, const T y) { count; // 记录调用次数 return x y; } };手搓代码#pragma once #includeiostream #includevector #includeassert.h using namespace std; templateclass T class Less { public: bool operator()(const T x, const T y) { return x y; } }; template class T class Greater { public: bool operator()(const T x, const T y) { return x y; } }; namespace cl { template class T,class Container vectorT,class Compare LessT class priority_queue { public: priority_queue() default;//强制编译器生成默认构造 //用一段迭代器区间去进行初始化 template class InputIterator priority_queue(InputIterator first, InputIterator last) :_con(first,last) { //向下调整建堆 //向下调整建堆是从最后一个非叶子节点开始即(_cin.size()-1-1)/2 这是一个父节点 for (int i (_con.size() - 1 - 1) / 2; i 0; i--) { adjust_down(i); } } void push(const T x) { _con.push_back(x); adjust_up(_con.size() - 1); } void pop() { assert(!empty()); swap(_con[0], _con[_con.size() - 1]); _con.pop_back(); adjust_down(0); } const T top() { assert(!empty()); return _con[0]; } bool empty() const { return _con.empty(); } size_t size() const { return _con.size(); } private: void adjust_up(int child) { Compare com; int parent (child - 1) / 2; while (child 0) { //if (_con[child] _con[parent]) //if(_con[parent]_con[child]) if (com(_con[parent], _con[child])) { swap(_con[child], _con[parent]); child parent; parent (child - 1)/2; } else { break; } } } void adjust_down(int parent) { //建立一个仿函数对象 Compare com; size_t child 2 * parent 1; while(child _con.size()) { // 如果右孩子存在并且右孩子比左孩子更满足比较规则则child选右孩子 //if (child 1 _con.size() _con[child] _con[child 1]) if (child 1 _con.size() com(_con[child], _con[child 1])) child; //if (_con[child] _con[parent]) if (com(_con[parent], _con[child])) { swap(_con[child], _con[parent]); parent child; child 2 * parent 1; } else break; } } private: Container _con; }; }
RELATED

相关推荐

Intel HD630非DCH驱动26.20.100.6573稳定适配指南

Intel HD630非DCH驱动26.20.100.6573稳定适配指南

简介:本资源为Intel HD Graphics 530(HD630)集成显卡专用的非DCH架构驱动程序,版本号26.20.100.6573,专为Windows 10 64位系统优化,适用于搭载第六代Skylake处理器的台式机与笔记本用户,解决传统…

📅 2026/10/14 19:30:26
OpenCV梯度方向彩色可视化:边缘检测的方向信息编码与Python实现

OpenCV梯度方向彩色可视化:边缘检测的方向信息编码与Python实现

做图像算法调试的人,大概率都经历过这种时刻:同一张图的边缘检测结果,你和一个同事盯着一份二值图争论“这条边缘到底是横向还是纵向”,最后谁也没说服谁。原因很简单——传统边缘检测输出的二值图,把梯度方向信息丢掉…

📅 2026/10/14 19:30:26
黑豹X2 panther x2 通过TF卡 更新系统 升级版本

黑豹X2 panther x2 通过TF卡 更新系统 升级版本

几年前买的一个armbian的黑豹x2 这几天 来折腾了下 之前的版本如下 /dev下没有mpp_service 就想着能不能升级下 以便于支持硬件加速挺折腾的 网上下了好几个固件 都有奇奇怪怪的问题 然后下了一个固件 不知道 是不完整还是咋的 dd写入到emmc之后 小盒子起不来了 表现现象为…

📅 2026/10/14 19:30:26
MORE NEWS

更多资讯

📰

Hyperframes:浏览器原生帧级动画实践指南

1. “hyperframes”不是新框架&#xff0c;而是浏览器原生动画范式的悄然升级最近在几个前端技术群和社区里&#xff0c;频繁看到“hyperframes”这个词被提起——有人在问“hyperframes怎么安装”&#xff0c;有人贴出带<hyperframe>标签的代码片段&#xff0c;还有人说…

📰

C/C++栈破坏分析:从崩溃定位到根因追溯的实战方法论

1. 项目概述&#xff1a;为什么栈破坏分析是 crash 调试中绕不开的“硬骨头”“栈破坏分析”这四个字&#xff0c;听上去像教科书里的冷门章节&#xff0c;但只要你做过三年以上 C/C 系统级开发、嵌入式驱动调试&#xff0c;或者维护过任何需要长期稳定运行的服务端模块&#x…

📰

T3 Stack全栈模板:端到端类型安全的工程实践指南

t3code是我最近在整理的一个全栈模板项目代号&#xff0c;准确说&#xff0c;它不是某个第三方框架&#xff0c;而是我把过去两年用 T3 Stack 搭建、迭代、上线过的几套实际业务系统里沉淀出来的代码组织方式&#xff0c;集中到了一个可复现的模板里。这个模板的核心是端到端类…

📰

Python函数执行机制深度解析:默认参数、作用域与字节码

1. 这不是“刷题复盘”&#xff0c;而是一次Python底层执行逻辑的现场解剖很多人把“第4周测验复盘”当成查漏补缺的例行公事——错题改一改&#xff0c;标准答案抄一抄&#xff0c;分数凑够就翻篇。我带过十几期Python入门训练营&#xff0c;发现一个扎心事实&#xff1a;83%的…

📰

Qt信号与槽机制深度解析:从元对象系统到跨线程实战

1. 从一次界面卡死说起&#xff1a;为什么信号与槽不是“语法糖”刚接触Qt那会儿&#xff0c;我写过一个串口数据采集的小工具。界面上有个“开始采集”按钮&#xff0c;点击后在一个while循环里不停读数据、刷新文本框。结果程序一跑起来&#xff0c;窗口直接白屏&#xff0c;…

📰

纯血鸿蒙学生党三件套实测:拍照提取书页文字、课表签到备忘与本地电子书阅读

开学有一阵了&#xff0c;手机里最高频的其实不是游戏和短视频&#xff0c;而是几类学习搭子&#xff1a;课上拍板书、课后整理资料、平时查教学周、睡前看两页书。这学期我把这些需求收拢到三款纯血鸿蒙应用上——「OCR扫描匣」「课程表管家」「爱阅读」。它们的共同点很明确&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬