队列(STL_queue、数组模拟循环队列、单调队列)

文章介绍了如何使用STL库中的queue容器以及使用数组模拟循环队列,包括它们的基本操作如size(),push(),pop(),front()等。接着讨论了单调队列的概念,它保持元素的递增或递减顺序,并在特定条件下维护滑动窗口。最后,给出了一个使用单调队列解决滑动窗口最小值问题的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.STL_queue

size()              返回队列的元素数                   O(1)
push(x)             向队列中添加 x                     O(1)
pop()               在队列中取出队头元素并删除         O(1)
front()             返回队头元素                       O(1)
empty()             在队列为空是返回 true              O(1)

2.数组模拟循环队列

int head=0,tail=0,q[N];

//清空队列
void init_queue()
{
    head=0;
    tail=0;
}

//判断队列是否为空
bool isEmpty()
{
    return head==tail;
}

//判断队列是否已满
bool isFull()
{
    return head==(tail+1)%Max;
}

//入队
void push_q(int x)
{
    if(!isFull)
    {
        q[tail]=x;
        if(tail+1==Max) tail=0;
        else tail++;
    }
}

//出队
auto pop_q()
{
    if(!isFull)
    {
        auto x=q[head];
        head  = (head+1) == MAX ? 0 :(head+1)
        return x;
    }
    return 0;
}

3.单调队列

性质:

<1>队列中的元素在原来的列表中的位置是由前往后的

<2>队列中的元素的大小是 递增 或 递减 的

<3>从队首出列 从队首或队尾入列

例题:

 

#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int n, k, q[N], a[N];//q[N]存的是数组下标
int main()
{
    int tt = -1, hh=0;//hh队列头 tt队列尾

    cin>>n>>k;
    for(int i = 0; i <n; i ++) cin>>a[i];
    for(int i = 0; i < n; i ++)
    {
        //维持滑动窗口的大小
        //当队列不为空(hh <= tt) 且 当当前滑动窗口的大小(i - q[hh] + 1)>我们设定的
        //滑动窗口的大小(k),队列弹出队列头元素以维持滑动窗口的大小
        if(hh <= tt && k < i - q[hh] + 1) hh ++;
        //构造单调递增队列
        //当队列不为空(hh <= tt) 且 当队列队尾元素>=当前元素(a[i])时,那么队尾元素
        //就一定不是当前窗口最小值,删去队尾元素,加入当前元素(q[ ++ tt] = i)
        while(hh <= tt && a[q[tt]] >= a[i]) tt --;
        q[ ++ tt] = i;
        if(i + 1 >= k) printf("%d ", a[q[hh]]);
    }
    puts("");
    hh = 0,tt = -1;
    for(int i = 0; i < n; i ++)
    {
        if(hh <= tt && k < i - q[hh] + 1) hh ++;
        while(hh <= tt && a[q[tt]] <= a[i]) tt --;
        q[ ++ tt] = i;
        if(i + 1 >= k ) printf("%d ", a[q[hh]]);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值