详细内容
std::priority_queue
是C++ STL中提供的一种容器适配器,用于实现优先队列。它的特点是元素按照优先级排序,默认情况下是大顶堆,即每次访问或移除的都是当前最大元素。也可以通过指定比较函数,实现小顶堆或自定义优先级的队列。
1. 基本特点
默认情况下,
std::priority_queue
是基于最大堆(大顶堆)的优先队列,最大元素具有最高优先级。底层通常使用
std::vector
作为存储容器,并通过堆算法(heap)来维护优先级顺序。操作的时间复杂度为 O(log n),因为每次插入和删除操作都需要重新调整堆。
2. 定义与基本操作
2.1 定义优先队列
2.2 操作方法
push()
:将元素插入优先队列。pop()
:移除当前优先级最高的元素(对于大顶堆来说是最大元素)。top()
:返回优先级最高的元素,但不移除它。empty()
:判断优先队列是否为空。size()
:返回优先队列中元素的个数。
示例:
3. 自定义优先级
默认情况下,std::priority_queue
是大顶堆。如果希望实现小顶堆或自定义优先级,需要指定比较函数或仿函数。
3.1 小顶堆的实现
可以通过指定 std::greater<T>
作为比较函数,将优先队列变为小顶堆。
3.2 自定义比较规则
如果需要对复杂类型的对象进行排序,可以自定义比较规则。可以通过传入自定义的仿函数或函数对象来实现。
示例:自定义比较函数
在这个例子中,我们使用了自定义结构体 Person
并通过重载 <
运算符来定义优先队列的排序规则。
4. 复杂度
插入元素(
push()
):时间复杂度为 O(log n),因为每次插入时需要重新维护堆结构。删除元素(
pop()
):时间复杂度为 O(log n),移除顶元素后也需要重新维护堆。访问最大或最小元素(
top()
):时间复杂度为 O(1),因为顶元素始终是堆顶,不需要任何操作。
5. 适用场景
任务调度:当多个任务具有不同的优先级时,可以使用
std::priority_queue
按照优先级执行任务。贪心算法:很多贪心算法,如哈夫曼编码、Dijkstra 最短路径算法等,都依赖于优先队列来获取当前的最优解。
实时数据流:处理需要频繁获取最值的场景(如实时计算最大或最小元素)。
6. 总结
std::priority_queue
是一个强大的容器适配器,默认情况下实现大顶堆(最大优先队列)。通过自定义比较规则,可以实现小顶堆或其他自定义优先级队列。
适用于需要频繁处理具有优先级的元素集合的场景,如调度、排序、贪心算法等。
Last updated