You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

##AcWing 829. 模拟队列

一、题目描述

实现一个队列,队列初始为空,支持四种操作:

push x 向队尾插入一个数 x pop 从队头弹出一个数; empty 判断队列是否为空; query 查询队头元素。

现在要对队列进行 M 个操作,其中的每个操作 3 和操作 4 都要输出相应的结果。

输入格式 第一行包含整数 M,表示操作次数。

接下来 M 行,每行包含一个操作命令,操作命令为 push xpopemptyquery 中的一种。

输出格式 对于每个 emptyquery 操作都要输出一个查询结果,每个结果占一行。

其中,empty 操作的查询结果为 YESNOquery 操作的查询结果为一个整数,表示队头元素的值。

数据范围 1≤M≤100000,1≤x≤10^9 ,所有操作保证合法。

输入样例:

10
push 6
empty
query
pop
empty
push 3
push 4
pop
query
push 6

输出样例:

NO
6
YES
4

二、理解和感悟

用数组模拟队列,比用数组模拟栈要麻烦一点,因为栈是同一边进同一边出,而队列是尾巴进,脑袋出。

举个栗子 1、先加入一个元素a,那么需要++tt,就是tt==0,然后要求a出队,就是hh++,这时,hh=1,现在队列为空,hh>tt

2、因为数组的特点在数组后面增加元素很方便在头部增加元素很麻烦所以设计了hh在左,tt在右的策略,出队hh++,入队++tt

3、使用数组模拟队列的另一个好处就是可以遍历队列中的每一个数字这和用数组模拟栈是一样的这也是STL比不了的。

三、普通队列解法

#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 10;
int q[N], hh, tt = -1;
int main() {
    int n;
    cin >> n;
    while (n--) {
        string op;
        cin >> op;
        if (op == "push") cin >> q[++tt];
        else if (op == "empty")
            hh > tt ? cout << "YES" << endl : cout << "NO" << endl;
        else if (op == "query")
            cout << q[hh] << endl;
        else hh++;
    }
    return 0;
}

四、循环队列解法

#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 10;
int q[N], hh, tt;
int main() {
    int n;
    cin >> n;
    while (n--) {
        string op;
        cin >> op;
        if (op == "push") {
            cin >> q[tt++];
            if (tt == N) tt = 0; // 加冒了就回到0
        } else if (op == "empty")
            hh == tt ? cout << "YES" << endl : cout << "NO" << endl;
        else if (op == "query")
            printf("%d\n", q[hh]);
        else {
            hh++;
            if (hh == N) hh = 0; // 加冒了就回到0
        }
    }
    return 0;
}

五、总结

  • 普通队列的时候,插入时是q[++tt]
  • 循环队列的时候,插入时是q[tt++]

个人理解:如果真的队列N的数量不够,需要重复利用的话,那么进去队列的次数可不小。本来我们用数组模拟队列,一就是因为速度快,二就是因为可以利用数组找出入队列的顺序,也就是 拓扑序,要是真用了循环队列的话,那么被覆盖掉时,拓扑序也就没有机会再找出来了,还不如直接用STLqueue,一家之言,待后续的经验验证。