特殊队列

特殊队列

双端队列

从名字可以看出,它可以在队列两端进行操作,相当于栈和队列的结合。主要操作有4种:

  • 在队首插入一个元素
  • 在队尾插入一个元素
  • 在队首弹出一个元素
  • 在队尾弹出一个元素

deque

C++的STL提供了一个容器std::deque,使用时需要引入头文件<deque>

STL中的deque容器包含一些成员函数,比较常用的有:

deque<int>deq;
//查询
deq.front();    //查询队首元素
deq.back();     //查询队尾元素
deq.empty();    //查询队列是否为空
deq.size();     //查询队列元素个数
//修改
deq.push_front(x)//队首插入一个元素
deq.pop_front(x);   //队首删除一个元素
deq.push_back(x);   //队尾插入一个元素
deq.pop_back(x);    //队尾删除一个元素
deq.insert(i, x);   //在指定为之前插入一个元素(传入迭代器和元素)
deq.erase(i);       //删除指定位置的元素(传入迭代器)

另外,deque还有一些运算符,比较常用的有:

  • =deque 赋值,类似 queue
  • [] 查询 deque 中的元素,类似 vector, 。

优先队列

头文件 queue 中提供了优先队列 std::priority_queue ,与二叉堆相似,可以维护顶部元素大小,默认维护最大值。每次维护(即删除和插入)的时间复杂度为O(logn).

代码

//如果不使用using namespace std 名字空间,使用时应加上std::
std::priority_queue<int>heap;

int a[5] = {2, 1, 4, 5, 3};

//插入时的顶部元素最大值
for(int i = 0; i < 5; ++i){
    heap.push(a[i]);
    std::cout << heap.top() << ' '; //访问顶部元素
}
std::cout << '\n';
//输出:2 2 4 5 5

for(int i = 0; i < 5; ++i){
    std::cout << heap.top() << ' '; //访问顶部元素

    //弹出顶部元素
    heap.pop();
}
//输出:5 4 3 2 1

例题

P1177 【模板】快速排序

题目大意

给定 n 个数 a1n,要求对它们从小到大排序。(1n105 ,ai109)

题目思路

由上述可知优先队列可以维护最大值,所以可以进行排序,而这里需要从小到大排序,可以有几种解决方案,比如,将各个数的相反数加入优先队列中,或者先将答案从 n ~ 1 反向入数组中就可以了。优先队列每次操作的时间复杂度为 O(logn) ,总的时间复杂度为 O(nlogn) ,是可以过的。

完整代码

//这里用第一种方法
#include<cstdio>    //C语言风格
#include<iostream>  //C++语言风格
#include<queue>
using namespace std;

int main(void){
    priority_queue<int>heap;
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i){
        int a;
        scanf("%d", &a);
        //放入-a,访问时要用负号还原
        heap.push(-a);
    }
    for(int i = 1; i <= n; ++i){
        //注意,之前放入的是负数,使用时也应该先用负号还原成原来的数
        printf("%d ", -heap.top());
        heap.pop();
    }
    return 0;
}
posted @   言葉の庭  阅读(62)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示