一、题目描述
请你仅使用两个队列实现一个后入先出(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);
}