一、题目描述
原题链接:https://leetcode.cn/problems/implement-queue-using-stacks/
题目描述:
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
二、解题
思路分析:栈是先进后出,队列是后进先出,是完全相反的性质,如果要用栈实现队列,那么肯定需要两个栈来实现。
因为性质相反,所以两个栈之间肯定有倒数据的过程,接下来我们用动图来诠释大概过程
一个栈专门入数据,记为pushst,一个栈专门出数据,记为popst
入数据的时候只往pushst入,出数据的时候先判断popst为不为空,不为空直接出栈顶元素,为空将pushst倒空再出popst栈顶元素
经过这样的操作我们就会发现将栈的元素倒置了,也就间接实现了队列的性质——先进先出
因为本小白还没开始系统地学习c++的内容,所以这里的栈采用的是之前c语言实现的栈,相关接口在之前的博客,需要的小伙伴们可以自取:https://blog.csdn.net/fight_for1/article/details/130677877?spm=1001.2014.3001.5501
有了思路,代码实现起来也就水到渠成了
代码实现
typedef struct {
SLtack Pushtack;
SLtack Poptack;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
StackInit(&obj->Pushtack);
StackInit(&obj->Poptack);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
StackPush(&(obj->Pushtack),x);
}
int myQueuePop(MyQueue* obj) {
if(StackEmpty(&(obj->Poptack)))//如果POP栈为空,那么需要将Push栈的数据压入Pop栈中
{
while(!StackEmpty(&(obj->Pushtack)))
{
StackPush(&(obj->Poptack),StackTop(&(obj->Pushtack)));
StackPop(&(obj->Pushtack));
}
}
int pop=StackTop(&(obj->Poptack));
StackPop(&(obj->Poptack));
return pop;
}
int myQueuePeek(MyQueue* obj) {
if(StackEmpty(&(obj->Poptack)))//如果POP栈为空,那么需要将Push栈的数据压入Pop栈中
{
while(!StackEmpty(&(obj->Pushtack)))
{
StackPush(&(obj->Poptack),StackTop(&(obj->Pushtack)));
StackPop(&(obj->Pushtack));
}
}
return StackTop(&(obj->Poptack));
}
bool myQueueEmpty(MyQueue* obj) {
if(StackEmpty(&(obj->Pushtack))&&StackEmpty(&(obj->Poptack)))
return true;
else
return false;
}
void myQueueFree(MyQueue* obj) {
//先free掉栈,再free掉obj
StackDestroy(&(obj->Pushtack));
StackDestroy(&(obj->Poptack));
free(obj);
}