🐶博主主页:@ᰔᩚ. 一怀明月ꦿ
❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++,数据结构
🔥座右铭:“不要等到什么都没有了,才下定决心去做”
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀
目录
用队列实现栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(
push
、top
、pop
和empty
)。实现
MyStack
类:
void push(int x)
将元素 x 压入栈顶。int pop()
移除并返回栈顶元素。int top()
返回栈顶元素。boolean empty()
如果栈是空的,返回true
;否则,返回false
。注意:
- 你只能使用队列的基本操作 —— 也就是
push to back
、peek/pop from front
、size
和is empty
这些操作。- 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入: ["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 <= x <= 9
- 最多调用
100
次push
、pop
、top
和empty
- 每次调用
pop
和top
都保证栈不为空注意:这题没有队列的具体实现的源码,得自己实现
解题思路:
我们知道队列的特点是先进先出原则,而栈的特点是先先进后出原则,用一个队列是无法实现栈的,所以我们可以用两个队列去完成栈的实现。一个对列始终保持空的状态,一个存储数据的状态,当然这两个队列的状态不是固定的,可以来回切换。具体实现如下:
栈的结构体创建
这个栈有两个队列,所以我们用结构体去存储
typedef struct { Queue q1; Queue q2; } MyStack;
栈的初始化
这里动态实例一个栈,并且调用队列的初始化函数对两个队列进行初始化
MyStack* myStackCreate() { MyStack* obj=(MyStack*)malloc(sizeof(MyStack)); 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* EMPTY=&obj->q1; Queue* FULL=&obj->q2; if(!QueueEmpty(&obj->q1)) { EMPTY=&obj->q2; FULL=&obj->q1; } while(QueueSize(FULL)>1) { QueuePush(EMPTY,QueueFront(FULL)); QueuePop(FULL); } int top=QueueFront(FULL); QueuePop(FULL); return top; }
栈顶元素
首先我们的找那个是为空状态的队列,哪个是存储数据状态的队列,然后将存储数据的队列的数据传递给为空的队列并传递一个数据,为空数据的队列就出队列一次。直到存储数据的队列只剩一个数据,记录这个数据,将存储数据的队列最后一个数据传递给为空的栈,然后将存储数据的队列再出队列一次,这样两个队列的状态互换。最后返回存储的数据。
int myStackTop(MyStack* obj) { Queue* EMPTY=&obj->q1; Queue* FULL=&obj->q2; if(!QueueEmpty(&obj->q1)) { EMPTY=&obj->q2; FULL=&obj->q1; } while(QueueSize(FULL)>1) { QueuePush(EMPTY,QueueFront(FULL)); QueuePop(FULL); } int top=QueueFront(FULL); QueuePush(EMPTY,QueueFront(FULL)); QueuePop(FULL); return top; }
栈的判空
两个队列为空,即栈为空
bool myStackEmpty(MyStack* obj) { return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2); }
栈的销毁
先销毁两个链表,然后销毁动态创建的栈
void myStackFree(MyStack* obj) { QueueDestroy(&obj->q1); QueueDestroy(&obj->q2); free(obj); }
用队列实现栈
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(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(双端队列)来模拟一个栈,只要是标准的栈操作即可。
示例 1:
输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
提示:
1 <= x <= 9
最多调用 100 次 push、pop、peek 和 empty
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)
注意:本题没有对队列具体实现的源码,需要自己去实现队列
解题思路:
我们知道队列的特点是先进先出原则,而栈的特点是先先进后出原则,用一个栈是无法实现队列的,所以我们可以用两个栈去完成队列的实现。一个栈用于出队列,另一栈进行入队列。具体实现:
队列的结构
typedef struct { Stack pushst; Stack popst; } MyQueue;
队列的初始化
MyQueue* myQueueCreate() { MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue)); StackInit(&obj->pushst); StackInit(&obj->popst); return obj; }
入队列
我们只需要将数据插入到pushst的队列中
void myQueuePush(MyQueue* obj, int x) { StackPush(&obj->pushst,x); }
出队列
如果队列不为空,我们需要判断popst栈中否有数据,如果没有我们需要将pushst栈中的数据传递给posst栈中,每传递一次pushst就出栈一次。直到将pusht的数据全部传递给popst。然后记录popst栈顶数据,将popst出栈一次,最后返回记录的栈顶数据。
int myQueuePop(MyQueue* obj) { int top=myQueuePeek(obj); StackPop(&obj->popst); return top; }
队头元素
如果队列不为空,我们需要判断popst栈中否有数据,如果没有我们需要将pushst栈中的数据传递给posst栈中,每传递一次pushst就出栈一次。直到将pusht的数据全部传递给popst。然后记录popst栈顶数据,最后返回记录的栈顶数据。
int myQueuePeek(MyQueue* obj) { if(StackEmpty(&obj->popst)) { while(!StackEmpty(&obj->pushst)) { StackPush(&obj->popst,StackTop(&obj->pushst)); StackPop(&obj->pushst); } } return StackTop(&obj->popst); }
队列的判空
bool myQueueEmpty(MyQueue* obj) { return StackEmpty(&obj->pushst)&&StackEmpty(&obj->popst); }
队列的销毁
void myQueueFree(MyQueue* obj) { StackDestroy(&obj->pushst); StackDestroy(&obj->popst); free(obj); }
🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸