队列、栈

1、双向队列

描述
    新建的 Beijing Institute Group 银行 (BIG-Bank) 在北理工开了一个营业点,他们装备了由 IBM Coral Studio 提供的现代化计算环境,使用现代的信息技术。通常,每个银行客户都有唯一的用来标识身份的正整数 K ,而每当他来到银行寻求服务时,银行都会给他一个正整数 P ,代表他的优先权。银行一个年轻的管理员李凌对软件服务系统的功能十分惊讶。他建议打破银行传统的最低优先权优先的服务方式,加入最高优先权优先的服务。于是,软件系统将得到如下类型的请求:

    0 系统终止服务
    1 K P 将客户 K 加到等待队列中,并赋优先权 P
    2 为有最高优先权的人服务,并将他从等待队列中删除
    3 为有最低优先权的人服务,并将他从等待队列中删除
    银行的软件工程师张国文现在抽不开身,请你替他写一个程序实现这种服务策略。
输入
    输入的每行包含一个可能的请求,只有最后一行是停止请求 ( 代码 0) 。你可以认为每个加入客户的请求 ( 代码 1) 中,赋予的优先权都是不同的。每个标识 K 都是小于 106 的数,优先权 P 都是小于 107 的数,客户可能请求多次服务,每次都会得到不同的优先权。
输出
    对每个代码为 2 或 3 的请求,程序必须打印被服务的客户的标识。如果此时队列是空,那么打印 0 。
样例输入

    2
    1 20 14
    1 30 3
    2
    1 10 99
    3
    2
    2
    0

样例输出

    0
    20
    30
    10
    0

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
int cmd;

struct Node {
    int Rank;
    int key;
};

Node node;

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    int K, P;
    deque<Node>Deque;
    while (scanf("%d", &cmd) && cmd != 0) {
        if (cmd == 1) {
            scanf("%d%d", &K, &P);
            node.key = K; node.Rank = P;
            if (Deque.empty()) {
                Deque.push_front(node);
            } else {
                if (P < Deque.front().Rank) {
                    Deque.push_front(node);
                } else if (P > Deque.back().Rank) {
                    Deque.push_back(node);
                } else {
                    deque<Node>::iterator itr;
                    for (itr = Deque.begin(); itr != Deque.end(); ++itr) {
                        if (itr->Rank > P) {
                            Deque.insert(itr, 1, node);
                            break;
                        }
                    }
                }
            }
        } else if (cmd == 2) {
            if (Deque.empty()) {
                printf("0\n");
            } else {
                printf("%d\n", Deque.back().key);
                Deque.pop_back();
            }
        } else {
            if (Deque.empty()) {
                printf("0\n");
            } else {
                printf("%d\n", Deque.front().key);
                Deque.pop_front();
            }
        }
    }
    return 0;
}


2、nucoj 1926 队列极值

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>
#include <cassert>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define eps 1e-9

typedef long long ll;
typedef pair<int, int> pii;

const int INF = 0x7fffffff;
const int maxn = 5e5 + 10;
int n, x, Case = 0;
char cmd[10];
struct Stack {
    int cur, max_cur, min_cur;
    int item[maxn], next_max[maxn], next_min[maxn];
    Stack(int x = -1, int y = -1, int z = -1):cur(x),max_cur(y),min_cur(z){}
    inline bool empty() { return cur == -1 ? true : false; }
    inline int top() { return item[cur]; }
    inline int Max() { return max_cur == -1 ? -INF : item[max_cur]; }
    inline int Min() { return min_cur == -1 ? INF : item[min_cur]; }
    inline void push(int x) {
        ++cur; item[cur] = x;
        if (x > Max()) { next_max[cur] = max_cur; max_cur = cur; } else { next_max[cur] = -1; }
        if (x < Min()) { next_min[cur] = min_cur; min_cur = cur; } else { next_min[cur] = -1; }
    }
    inline void pop() {
        if (cur == max_cur) { max_cur = next_max[cur]; }
        if (cur == min_cur) { min_cur = next_min[cur]; } --cur;
    }
};
struct Queue {
    Stack a, b;
    inline bool empty() { if (a.empty() && b.empty()) { return true; } return false; }
    inline void clear() { a.cur = a.max_cur = a.min_cur = b.cur = b.max_cur = b.min_cur = -1; }
    inline void push(int x) { b.push(x); }
    inline int front() {
        if (a.empty()) { while (!b.empty()) { a.push(b.top()); b.pop(); } } return a.top();
    }
    inline void pop() {
        if (a.empty()) { while (!b.empty()) { a.push(b.top()); b.pop(); } } a.pop();
    }
    inline int Max() { return max(a.Max(), b.Max()); }
    inline int Min() { return min(a.Min(), b.Min()); }
};
Queue q;

int main() {
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    while (scanf("%d", &n) && n != 0) {
        printf("Case %d:\n", ++Case); q.clear();
        while (n--) {
            scanf("%s", cmd);
            if (cmd[0] == 'E') { scanf("%d", &x); q.push(x); continue; }
            if (q.empty()) { printf("EMPTY!\n"); continue; }
            if (cmd[0] == 'D') { printf("%d\n", q.front()); q.pop(); }
            else if (cmd[1] == 'A') { printf("%d\n", q.Max()); }
            else { printf("%d\n", q.Min()); }
        }
    }
#ifdef __AiR_H
    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
    return 0;
}












<think>好的,我现在需要帮用户解决如何用两个实现队列,并处理满的情况。首先,我得回忆一下队列的基本特性。是后进先出(LIFO),而队列是先进先出(FIFO)。所以用两个模拟队列的关键点应该在于如何反转元素的顺序。 根据之前学过的知识,常见的方法是用两个,一个作为输入,另一个作为输出。当需要入队时,元素压入输入;出队时,如果输出为空,就把输入的所有元素依次弹出并压入输出,这样输出顶就是最先进入的元素,符合队列的特性。 用户还提到了满的情况,这在实际应用中需要考虑,特别是当内存有限时。的实现通常有容量限制,所以当输入已满时,如何处理新的入队操作是需要解决的问题。这时候可能需要将输入的元素转移到输出,或者扩展的容量。不过直接转移可能会导致顺序问题,需要仔细处理。 另外,参考用户提供的引用内容,比如引用[3]提到将1的数据倒入2,这样2的出顺序就和队列一样。引用[4]中的结构体使用了两个队列,但这里的问题是用两个实现队列,结构上可能需要类似的双结构。 处理满的情况,可能的解决方法包括: 1. 在入队操作前检查输入是否已满,如果满了,尝试将元素转移到输出,腾出空间。 2. 如果转移后输入仍有空间,继续入队;如果转移后仍然满,可能需要报错或者动态扩容。 3. 动态扩容的话,需要考虑复制元素到更大的数组,但这会增加时间复杂度。 接下来要考虑的是如何具体实现这些步骤,以及在代码中如何处理边界情况,比如两个都满的情况是否可能发生,或者如何处理并发操作等问题。不过用户可能更关注基本的实现和满的处理,所以需要简明扼要地解释方法,并给出示例代码。 最后,还需要生成相关问题,帮助用户进一步学习,比如性能分析、优化方法等,这些可以基于现有的实现和问题点来设计。</think>### 如何用两个实现队列及处理满情况? #### 一、实现原理 用两个实现队列的核心思路是**通过两个反转数据顺序**,使得入队和出队操作分别对应的压入和弹出逻辑: 1. **输入(`stack_in`)**:负责接收新元素(入队操作)。 2. **输出(`stack_out`)**:负责弹出旧元素(出队操作)。 当执行**出队操作**时: - 若输出为空,将输入的所有元素依次弹出并压入输出,此时输出顶即为队列头部元素。 - 若输出非空,直接弹出顶元素。 #### 二、代码实现(Python示例) ```python class QueueWithTwoStacks: def __init__(self, max_size): self.stack_in = [] self.stack_out = [] self.max_size = max_size # 单个的最大容量 def enqueue(self, x): if self.is_full(): raise Exception("Queue is full") self.stack_in.append(x) def dequeue(self): if self.is_empty(): raise Exception("Queue is empty") if not self.stack_out: while self.stack_in: self.stack_out.append(self.stack_in.pop()) return self.stack_out.pop() def is_empty(self): return not self.stack_in and not self.stack_out def is_full(self): return len(self.stack_in) >= self.max_size ``` #### 三、满情况的处理方法 当输入达到容量上限时,需根据场景选择策略: 1. **动态扩容**:允许自动扩展容量(如Python列表默认行为),但需注意时间复杂度波动。 2. **拒绝写入**:直接抛出异常(如上述代码示例),适用于资源受限场景。 3. **强制转移**:将输入元素转移到输出,腾出空间(需确保输出未满): ```python def enqueue(self, x): if self.is_full(): if not self.stack_out: # 若输出为空,可以转移 while self.stack_in: self.stack_out.append(self.stack_in.pop()) else: raise Exception("Queue is full") self.stack_in.append(x) ``` #### 四、复杂度分析 | 操作 | 时间复杂度(均摊) | 空间复杂度 | |------------|--------------------|------------| | 入队 | $O(1)$ | $O(n)$ | | 出队 | $O(1)$[^3] | | #### 五、应用场景 - 线程安全的队列实现(如生产者-消费者模型)。 - 需要限制队列容量的场景(如流量控制)[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值