由两个栈组成的队列

本文介绍了一种使用两个栈来实现队列的方法,详细解释了如何通过特定的push、pop和top操作保持队列特性。当执行pop或top操作时,会确保第一个栈的所有元素已转移至第二个栈,从而正确地按队列顺序返回元素。

题目

编写一个类,用两个栈实现队列,支持队列的基本操作有(push,pop,top)

解题思路

开始自己的思路有点偏差,想着是在push时就完成从stack1到stack2的迁移,但是实际上并没有必要

push时只进行push操作即可,push向stack1放入一个数据。在pop时,首先判断两个栈是否都为空,若是则当前队列为空;否则必须
在将stack1中的所有元素放入之后才能逐个从stack2逐个pop元素。
在取队列的顶元素时,与pop操作一样,要确定stack1中的元素已经
全部放入stack2中,此时才能返回队列顶元素
具体题解可参考书籍

代码

#include<iostream>
#include<stack>
using namespace std;

class stackToQueue {
private:
	stack<int> stack1;
	stack<int> stack2;
public:
	void mPush(int val);
	void mPop();
	int mPeek();
};

void stackToQueue::mPush(int val)
{
	stack1.push(val);
}

void stackToQueue::mPop()
{
	if (stack1.empty() && stack2.empty())
		printf("The queue is empty!\n");
	else if (stack2.empty())
	{
		while (!stack1.empty())
		{
			stack2.push(stack1.top());
			stack1.pop();
		}
	}
	stack2.pop();
}

int stackToQueue::mPeek()
{
	if (stack1.empty() && stack2.empty())
		printf("The queue is empty!\n");
	else if (stack2.empty())
	{
		while (!stack1.empty())
		{
			stack2.push(stack1.top());
			stack1.pop();
		}
	}
	return stack2.top();
}

int main()
{
	stackToQueue myQueue;
	for (int i = 0; i < 3; i++)
		myQueue.mPush(i);
	for (int j = 0; j < 3; j++)
	{
		cout << myQueue.mPeek() << endl;
		myQueue.mPop();
	}
	for (int i = 3; i < 5; i++)
		myQueue.mPush(i);
	for (int j = 0; j < 2; j++)
	{
		cout << myQueue.mPeek() << endl;
		myQueue.mPop();
	}
	getchar();
	return 0;
}
在数据结构中,(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、付费专栏及课程。

余额充值