【刷题】225. 用队列实现栈

本文描述了一种使用两个队列来模拟栈的方法,支持push、pop、top和empty等操作。在push时直接向非空队列添加元素,pop时将非空队列的元素转移到另一个队列再弹出最后一个元素。栈顶元素即为非空队列的最后一个元素。
摘要由CSDN通过智能技术生成


225. 用队列实现栈

一、题目描述

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

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

二、示例

输入:[“MyStack”, “push”, “push”, “top”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:[null, null, null, 2, 2, false]
解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

三、实现

使用两个队列可以实现一个栈:
1.push操作时,往空队列q1插入数据,如push了1,2,3,4。
2.pop时,需要弹出元素4,此时队列q2为空,将队列q1的元素1,2,3依次出队插入到队列q2中,这样队列q2数据为1,2,3。然后队列最后一个元素4出队即可。

总之:
Push插入时:往非空队列插入数据。
Pop出栈时:需要将非空队列的非最后一个元素移到空队列中,然后再将最后一个元素弹出。

队列的实现参考:【C语言实现队列(链式队列)

3.1 MyStack定义

typedef struct {
	Queue q1;
	Queue q2;
} MyStack;

3.2 栈的初始化与销毁:

MyStack* myStackCreate() {
	MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
	if (obj == NULL)
	{
		perror("malloc fail");
		return NULL;
	}

	QueueInit(&obj->q1);
	QueueInit(&obj->q2);

	return obj;
}

void myStackFree(MyStack* obj) {
	QueueDestroy(&obj->q1);
	QueueDestroy(&obj->q2);
	free(obj);
}

3.3 栈的判空:

bool myStackEmpty(MyStack* obj) {
	// 两个队列都为空时栈才为空
	return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}

3.4 得到栈顶元素:

int myStackTop(MyStack* obj) {
	// 栈顶元素就是非空队列的队尾元素
	if (!QueueEmpty(&obj->q1))
	{
		return QueueBack(&obj->q1);
	}
	else
	{
		return QueueBack(&obj->q2);
	}
}

3.5 入栈操作:

void myStackPush(MyStack* obj, int x) {
	// 插入就是往非空队列的入队操作
	if (!QueueEmpty(&obj->q1))
	{
		QueuePush(&obj->q1, x);
	}
	else
	{
		QueuePush(&obj->q2, x);
	}
}

3.6 出栈操作:

int myStackPop(MyStack* obj) {
	Queue* pEmptyQ = &obj->q1;
	Queue* pNonEmptyQ = &obj->q2;
	if (!QueueEmpty(&obj->q1))
	{
		pEmptyQ = &obj->q2;
		pNonEmptyQ = &obj->q1;
	}

	// 1.将非空队列 除最后一个元素外其余元素 移到空队列中
	while (QueueSize(pNonEmptyQ) > 1)
	{
		QueuePush(pEmptyQ, QueueFront(pNonEmptyQ));
		QueuePop(pNonEmptyQ);
	}

	// 2.将原非空队列最后一个元素弹出
	QDataType top = QueueFront(pNonEmptyQ);
	QueuePop(pNonEmptyQ);
	
	return top;
}

完整接口实现

typedef struct {
	Queue q1;
	Queue q2;
} MyStack;


MyStack* myStackCreate() {
	MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
	if (obj == NULL)
	{
		perror("malloc fail");
		return NULL;
	}

	QueueInit(&obj->q1);
	QueueInit(&obj->q2);

	return obj;
}

void myStackPush(MyStack* obj, int x) {
	// 插入就是往非空队列的入队操作
	if (!QueueEmpty(&obj->q1))
	{
		QueuePush(&obj->q1, x);
	}
	else
	{
		QueuePush(&obj->q2, x);
	}
}

int myStackPop(MyStack* obj) {
	Queue* pEmptyQ = &obj->q1;
	Queue* pNonEmptyQ = &obj->q2;
	if (!QueueEmpty(&obj->q1))
	{
		pEmptyQ = &obj->q2;
		pNonEmptyQ = &obj->q1;
	}

	// 1.将非空队列 除最后一个元素外其余元素 移到空队列中
	while (QueueSize(pNonEmptyQ) > 1)
	{
		QueuePush(pEmptyQ, QueueFront(pNonEmptyQ));
		QueuePop(pNonEmptyQ);
	}

	// 2.将原非空队列最后一个元素弹出
	QDataType top = QueueFront(pNonEmptyQ);
	QueuePop(pNonEmptyQ);
	
	return top;
}

int myStackTop(MyStack* obj) {
	// 栈顶元素就是非空队列的队尾元素
	if (!QueueEmpty(&obj->q1))
	{
		return QueueBack(&obj->q1);
	}
	else
	{
		return QueueBack(&obj->q2);
	}
}

bool myStackEmpty(MyStack* obj) {
	// 两个队列都为空时栈才为空
	return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}

void myStackFree(MyStack* obj) {
	QueueDestroy(&obj->q1);
	QueueDestroy(&obj->q2);
	free(obj);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shlyyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值