算法通关村第五关白银挑战——栈与队列的实现问题分析

大家好,我是怒码少年小码。

栈和队列,大家都懂了,那么如何让这两个互选转化?

用栈实现队列

队列的特点是先进先出,但是栈的特点是后进先出,这个可咋整?

这也是LeetCode 232:使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push,pop,peek,empty)

我们先用输入栈保存入队的元素,再把它们弹出,然后进入输出栈,这样我们从输出栈顶取出的元素就是最先进入输入栈的元素了。

人话:用两个栈捣鼓了两遍,把顺序颠倒了一下。

输入输入栈的元素:1、2、3,输入栈弹出的元素3、2、1;进入输出栈的元素:3、2、1,输出栈弹出的元素:1、2、3

//定义
struct Queue {
	stack<int> inStack;
	stack<int> outStack;
};
//入队
void push01(Queue* queue, int x) {
		queue->inStack.push(x);
}
//出队
int pop01(Queue* queue) {
	if (queue->outStack.empty()) {
		while (!queue->inStack.empty() ) {
			int cur = queue->inStack.top();
			queue->inStack.pop();
			queue->outStack.push(cur);
		}
	}
	if (queue->outStack.empty()) {
		cout << "队列空了" << endl;
		return -1;
	}
	int val = queue->outStack.top();
	queue->outStack.pop();

	return val;
}
//获取队首元素
int peek(Queue* queue) {
	if (queue->outStack.empty()) {
		while (!queue->inStack.empty()) {
			int cur = queue->inStack.top();
			queue->inStack.pop();
			queue->outStack.push(cur);
		}
	}
	if (queue->outStack.empty()) {
		cout << "队列空了" << endl;
		return -1;
	}
	return queue->outStack.top();
}
//判空
bool empty01(Queue* queue) {
	if (queue->inStack.empty() && queue->outStack.empty()) {
		cout << "队列空了" << endl;
		return true;
	}
	else {
		cout << "还有还有" << endl;
		return false;
	}
}

这里为了方便我使用了C++的标准库stack,记得引入#include<stack>

值得注意的是:pop()的作用删除栈顶元素,它没有返回值,代码中的 int val = queue->outStack.top(); queue->outStack.pop();不可以写成int val = queue->outStack.pop();

测试一下:

int main() {
	Queue queue;
	push01(&queue, 1);
	push01(&queue, 2);
	push01(&queue, 3);
	pop01(&queue);
	int a=peek(&queue);
	cout << a << endl;
	cout << empty01(&queue) << endl;
}

用队列实现栈

LeetCode225:使用两个队列实现一个后入先出的栈,并支持普通栈的全部四种操作(push,top,pop,empty)。

思路:queue1用于存储栈内的元素,queue2作为入栈操作的辅助队列,入栈操作时,首先将元素入队到queue2,然后将queue1的全部元素依次出队并入队到queue2,此时queue2的前端的元素即为新入栈的元素,再将queue1和queue2互换,则queue1的元素即为栈内的元素,queue1的前端和后端分别对应栈顶和栈底。

class MyStack {
private:
	queue<int> queue1; // 主队列
	queue<int> queue2; // 辅助队列

public:
	MyStack() {}
	void push(int x) {
		// 将新元素入队到辅助队列
		queue2.push(x);
		// 将主队列的元素依次入队到辅助队列
		while (!queue1.empty()) {
			queue2.push(queue1.front());
			queue1.pop();
		}

		// 交换主队列和辅助队列
		swap(queue1, queue2);
	}

	int pop() {
		int topElement = queue1.front();
		queue1.pop();
		return topElement;
	}

	int top() {
		return queue1.front();
	}

	bool empty() {
		return queue1.empty();
	}
};

例如分别入栈1、2、3;1进入queue2,此时queue1为空,直接交换queue1和queue2,此时:

  • queue1:1
  • queue2:

然后2进入queue2,此时queue1不为空,把queue1中的元素出队并入队到queue2,此时:

  • queue1:
  • queue2:2,1

此时queue2的顺序已经排好,然后交换queue1和queue2:

  • queue1:2,1
  • queue2:

然后3进入queue2,此时queue1不为空,把queue1中的元素出队并入队到queue2,此时:

  • queue1:
  • queue2:3,2,1

此时queue2的顺序已经排好,然后交换queue1和queue2:

  • queue1:3,2,1
  • queue2:

这样就排好了!queue1出队的效果和出栈一样,实现了后进先出

出栈操作只需要移除queue1的前端元素并返回即可,获得栈顶元素操作只需要获得queue1的前端元素并返回即可(不移除元素)。由于queue1用于存储站内的元素,判断栈是否为空时,只需要判断queue1是否为空即可。

写一段代码测试一下:

	MyStack stack;
	stack.push(1);
	stack.push(2);
	stack.push(3);
	cout << "Top element: " << stack.top() << endl;
	cout << "Pop element: " << stack.pop() << endl;
	cout << "Top element: " << stack.top() << endl;
	return 0;

END

这篇理解起来不难,但是如果你不用C++的标准库估计要写上一会了😊~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值