priority_queue的介绍:

翻译:
优先队列是一种容器适配器(Container Adaptor),其设计遵循严格弱序(Strict Weak Ordering)原则,确保队列的首个元素始终是所有元素中的最大值。
这一特性与堆(Heap)数据结构高度相似:元素可以随时插入队列,而只能检索到最大元素(即优先队列顶部的元素)。
优先队列通过封装特定容器类的对象作为底层容器(Underlying Container)来实现,并提供一组特定的成员函数访问元素。元素从底层容器的 "尾部" 弹出,该位置对应优先队列的顶部。
底层容器可以是任何标准容器类模板或其他专门设计的容器类,但必须满足以下条件:
- 支持随机访问迭代器(Random Access Iterators)
- 提供以下操作:
- empty ():判断容器是否为空
- size ():返回容器大小
- front ():访问首个元素
- push_back ():在尾部插入元素
- pop_back ():删除尾部元素
标准容器 vector 和 deque 完全满足这些要求。默认情况下,如果未显式指定底层容器,优先队列将使用 vector 作为其底层实现。
优先队列通过随机访问迭代器在内部维护一个堆结构。当需要调整堆结构时,容器适配器会自动调用以下算法函数:
- make_heap ():构造堆结构
- push_heap ():插入元素后调整堆
- pop_heap ():删除元素前调整堆
这种设计确保优先队列在插入和删除操作后,始终保持堆的性质,从而高效地维护元素的优先级顺序。

可以看到模板第一个class T,是数据类型
第二个class Container=vactor<T>,这是一个默认以vector为底层容器
第三个class Compare=less<>,这是一个默认以系统实现的仿函数(后面讲解)(默认大堆)
priority_queue的使用
成员函数:
top():返回堆顶数据
pop():删除堆顶数据
其他通过前面的学习也知道
理解仿函数:

通过观察,可以发现默认是一个大堆
我们可以改掉仿函数,因为默认使用了less

此时是一个小堆,堆顶是最小的数据(如果没有学过堆,可以去看我数据结构一栏的讲解)
接下来我们讲解仿函数less和greater

这两个函数在<functional>的头文件中

可以发现这就是一个类
也就是less是一个类名,它重载了一个operator(),注意返回的是x<y (第一个小于第二个就返true)
如果这是一个类,你是否可以这样使用less<int> funless;funless(1,2),显然这是可以的

为什么叫仿函数???
如果单独看funless,你是以为它是一个函数,还是一个类对象呢???
所以仿函数:在 C++ 中,仿函数(Functor) 也称为 函数对象(Function Object),是一种行为类似函数的对象。它通过重载 operator() 运算符,使得对象可以像函数一样被调用。 、
那greater又是怎么一回事???(相信已经可以联想到了)

返回的是x>y(只要x>y就返回true)
是否可以自己动手写一个仿函数后传进去???
显然这是可以的

如何理解priority_queue中的仿函数调用???

再次回顾参数,可以看到class Compare=less<typename Container::value_type>
现在重新看是否理解不一样,less<这里面是底层容器的数据类型>
Compare默认使用less
所以你在模拟实现的时候可以先创建一个仿函数类的成员,或者你可以直接构建一个类对象
比如你在成员那里直接Compare _com;或者每次调用的地方在创建类对象也行

比如这种直接设成成员,那你后面用的时候可以直接_com(),传两个参数即可
_com就是类对象,当你调用_com()的时候会调类对象的operator()
模拟实现priority_queue
June: 这里包含我的c++和Linux及数据结构
https://gitee.com/taifanshu/day2.git已上传gitee,需要可以自己取
总结:
适配器都不支持迭代器遍历,因为需要保持自身的一些特性
但是底层容器可以支持,只是适配器不对外设接口
优先级队列底层就是一个堆,在解决堆问题时可以用优先级队列
1310

被折叠的 条评论
为什么被折叠?



