由两个栈组成的队列

博客主要讲述编写一个类,用两个栈实现队列,支持队列基本操作add、poll、peek。同时给出两个操作规则,一是stackPush往stackPop压入数据时要一次性全压入;二是stackPop不为空时,stackPush不能向其压入数据。

题目
编写一个类,用两个栈实现队列,支持队列的基本操作(add、poll、peek)。

解答
必须做到以下两点:
1. 如果stackPush 要往 stackPop 中压入数据,那么必须一次性把stackPush中的数据全部压入。
2. 如果stackPop 不为空,stackPush绝对不能向stackPop中压入数据。

代码

// 用两个栈组成的队列

import java.util.*;

public class TwoStackQueue {
    public Stack<Integer> stackPush;
    public Stack<Integer> stackPop;

    public TwoStackQueue() {
        stackPush = new Stack<Integer>();
        stackPop = new Stack<Integer>();
    }

    public void add(int pushInt) {
        stackPush.push(pushInt);
    }

    public int poll() {
        if (stackPop.empty() && stackPush.empty()) {
            throw new RuntimeException("Queue is empty!");
        } else if (stackPop.empty()) {
            while (!stackPush.empty()) {
                stackPop.push(stackPush.pop());
            }
        }
        return stackPop.pop();
    }

    public int peek() {
        if (stackPop.empty() && stackPush.empty()) {
            throw new RuntimeException("Queue is empty!");
        } else if (stackPop.empty()) {
            while (!stackPush.empty()) {
                stackPop.push(stackPush.pop());
            }
        }
        return stackPop.peek();
    }

    public static void main(String[] args) {
        TwoStackQueue tsq = new TwoStackQueue();
        tsq.add(2);
        tsq.add(4);
        tsq.add(3);
        tsq.add(1);
        System.out.println(tsq.poll());
        System.out.println(tsq.peek());
    }
}   
在数据结构中,(stack)是后进先出(LIFO)的结构,而队列(queue)是先进先出(FIFO)的结构。我们可以使用两个来模拟队列的行为。 实现思路如下: 1. 使用两个 `stack1` `stack2`。 2. **入队操作(enqueue)**:始终将元素压入 `stack1`。 3. **出队操作(dequeue)**: - 如果 `stack2` 为空,则将 `stack1` 中的所有元素依次弹出并压入 `stack2`,这样原本在 `stack1` 中底部的元素会出现在 `stack2` 的顶部,从而实现 FIFO。 - 然后从 `stack2` 弹出顶元素即可。 这种方法确保了每次出队时,元素顺序是按照队列的顺序来的。 下面是用 C 语言实现的代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 // 定义结构 typedef struct { int data[MAX_SIZE]; int top; } Stack; // 初始化 void initStack(Stack *s) { s->top = -1; } // 判断是否为空 int isEmpty(Stack *s) { return s->top == -1; } // 判断是否已满 int isFull(Stack *s) { return s->top == MAX_SIZE - 1; } // 入 void push(Stack *s, int value) { if (isFull(s)) { printf("Stack overflow\n"); exit(1); } s->data[++s->top] = value; } // 出 int pop(Stack *s) { if (isEmpty(s)) { printf("Stack underflow\n"); exit(1); } return s->data[s->top--]; } // 队列结构,由两个组成 typedef struct { Stack stack1; // 用于入队 Stack stack2; // 用于出队 } Queue; // 初始化队列 void initQueue(Queue *q) { initStack(&q->stack1); initStack(&q->stack2); } // 入队操作 void enqueue(Queue *q, int value) { push(&q->stack1, value); } // 出队操作 int dequeue(Queue *q) { // 如果 stack2 为空,把 stack1 的元素全部转移到 stack2 if (isEmpty(&q->stack2)) { while (!isEmpty(&q->stack1)) { push(&q->stack2, pop(&q->stack1)); } } // 如果 stack2 仍为空,说明队列为空 if (isEmpty(&q->stack2)) { printf("Queue is empty\n"); exit(1); } return pop(&q->stack2); } // 测试代码 int main() { Queue q; initQueue(&q); enqueue(&q, 10); enqueue(&q, 20); enqueue(&q, 30); printf("Dequeue: %d\n", dequeue(&q)); // 应输出 10 printf("Dequeue: %d\n", dequeue(&q)); // 应输出 20 enqueue(&q, 40); printf("Dequeue: %d\n", dequeue(&q)); // 应输出 30 printf("Dequeue: %d\n", dequeue(&q)); // 应输出 40 return 0; } ``` ### 代码解释: - `enqueue()`:将元素压入 `stack1`。 - `dequeue()`: - 若 `stack2` 为空,将 `stack1` 所有元素弹出并压入 `stack2`。 - 然后从 `stack2` 弹出元素,模拟队列的出队行为。 - 时间复杂度分析: - **入队操作**:O(1) - **出队操作**:均摊 O(1),因为每个元素最多被压入弹出两次。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值