【Containers】priority_queue 优先队列

简述

priority_queue(优先队列)是容器适配器,它提供常数时间的(默认)最大元素查找,对数代价的插入与释出。可用用户提供的 Compare 更改顺序,例如,用 std::greater<T> 将导致最小元素作为 top()出现。用 priority_queue 工作类似管理某些随机访问容器中的堆,优势是不可能突然把堆非法化。

简单来说priority_queue就是STL提供的一种利用堆排序(Heap Sort)的容器,这样我们以后用优先队列就不用再敲一遍堆排序了,关于堆排序的实现请参照另一篇博文【Algorithms】堆排序(Heap Sort)。

使用方法

那么知道了这个工具后我们怎么使用呢,接下来就是这个工具的使用说明书了~

首先我们要使用一个函数,需要添加函数所在的头文件,#include<queue>便是priority_queue的头文件。

接下来我们应该定义一个priority_queue对象,它在c++中的声明如下:

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;


priority_queue<Class T> q;  // 一般的构造方法,其中T为队列中存储的元素类型

在运用它之前还有一个工作要做,那就是学习如何操纵它,priority_queue常用函数如下表

元素访问

功能
top()访问堆顶元素,返回优先级最大的元素即堆顶元素

容量

 
empty()判断堆是否为空,如果为空返回true
size()返回堆内剩余元素个数

修改器

 
push()向优先队列后面添加一个元素,并对底层元素排序(保持优先队列)
pop()将堆顶元素出队,并对底层元素排序
swap(priority_queue)交换两个优先队列内的全部元素(要求两个队列类型、大小全部相同)
emplace()向优先队列顶部插入一个元素,并对底层元素排序

注:emplace()VS push()
当我们使用push()时,我们创建一个对象,然后将其插入priority_queue。使用emplace(),对象就地构造并保存不必要的副本。

代码示例:

#include<iostream>
#include<queue>
using namespace std;
int x[10]={1,5,7,9,6,3,8,4,2,0};
int main()
{
    priority_queue<int> q;
    for(int i=0;i<10;i++){
        q.push(x[i]);
    }
    while(!q.empty()){
        cout<<q.top()<<" ";
        q.pop();
    }
    return 0;
}

Output:

9 8 7 6 5 4 3 2 1 0

但是我们会发现,使用默认的优先队列,只能实现最大堆,这是因为优先队列默认的比较小于,也就是说堆的下移操作是基于小于号的,比较小的元素会放到下面,自然最大的元素就拍到堆顶啦d=====( ̄▽ ̄*)b,那么我们能不能实现小根优先队列呢?答案是肯定的,通过下面的语句对()运算符进行重载实现了大于比较的功能,因此也就可以实现最小优先队列啦

priority_queue<int, vector<int>, greater<int> > p;
#include<iostream>
#include<queue>
using namespace std;
int x[10]={1,5,7,9,6,3,8,4,2,0};
int main()
{
    priority_queue<int,vector<int>,greater<int> > q;
    for(int i=0;i<10;i++){
        q.push(x[i]);
    }
    while(!q.empty()){
        cout<<q.top()<<" ";
        q.pop();
    }
    return 0;
}

Output:

0 1 2 3 4 5 6 7 8 9

当然优先队列的用法不仅仅如此,还可以向队列中放入自定义类型,比如struct

#include<iostream>
#include<queue>
using namespace std;

typedef struct que
{
    int a,b;

    que(int x1,int x2){  //这里重载了que构造函数
            a=x1,b=x2;
    }

    friend bool operator< (que q1,que q2){  // 对运算符‘<’进行重载,不然无法进行排序,因为
            return q1.a > q2.a;             // c++内部的‘<’没有比较结构体的功能。
    }                                       // 并且注意这里要定义为友元,不然编译通不过
};                                          // 注:这里是通过重载小于号实现的最小优先队列哦

int main()
{
    int a,b;
    priority_queue<que> q; // que类型的优先队列
    for(int i=0;i<10;i++){
        cin>>a>>b;
        q.push(que(a,b));
    }
    while(!q.empty()){
        cout<<"a "<<q.top().a<<" b "<<q.top().b<<endl;;
        q.pop();
    }
    return 0;
}
Input:             Output:
1 9                a 0 b 0
2 8                a 1 b 9
3 7                a 2 b 8
4 6                a 3 b 7
5 5                a 4 b 6
6 4                a 5 b 5
7 3                a 6 b 4
8 2                a 7 b 3
9 1                a 8 B 2
0 0                a 9 b 1

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 根据您提供的引用内容,编译器内部错误:段错误通常是由于编译器或代码中的错误导致的。段错误是指程序访问了无效的内存地址,这可能是由于指针错误、内存越界或者其他内存相关的问题引起的。要解决这个问题,您可以尝试以下几个步骤: 1. 检查代码:首先,请确保您的代码没有明显的错误,比如指针未初始化、数组越界等。检查相关的代码行,特别是在/home/leb/brpc-1.6.0/src/butil/containers/doubly_buffered_data.h文件的第368行附近。 2. 更新编译器:如果您正在使用的是旧版本的编译器,尝试更新到最新版本,以确保您使用的是稳定的编译器版本。 3. 检查依赖项:根据您提供的引用内容,您正在使用的是一些第三方库。请确保这些库的版本与您的代码兼容,并且已正确安装和配置。 4. 检查系统环境:有时,系统环境中的问题也可能导致段错误。请确保您的系统环境配置正确,并且没有其他冲突或错误。 如果以上步骤都没有解决问题,您可能需要进一步调试代码或寻求更专业的技术支持来解决这个问题。 #### 引用[.reference_title] - *1* *2* *3* [yarn.lock · TeddyYoung/locker_vue - Gitee.com](https://blog.csdn.net/weixin_42511396/article/details/117683326)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值