用队列实现栈
链接:
https://leetcode.cn/problems/implement-stack-using-queues/
1. 要求
2. 思路
栈的性质是先进后出,队列的性质是先进先出。
题目要求是用两个队列来完成栈的实现,那么大思路就是通过倒腾数据来完成。
3. 代码实现
1. 入栈
入栈的情况分三种:
- 两个队列都为空
- 其中一个队列有数据,另一个没有
- 两个队列都有数据
所以,综上所有情况总结为一种情况就是,只要两个队列有一个为空即可入数据,否则不可以入数据。
void myStackPush(MyStack* obj, int x) {
if(QueueEmpty(&obj->q1)) {
QueuePush(&obj->q1,x);
}
else {
QueuePush(&obj->q2,x);
}
}
2. 出栈
出栈的情况就是当一个队列有数据,另一个队列为空时,才可以出栈。
类似这种情况。
出栈就是有数据的队列(q1)把 N-1 个数据都挪到 空队列(q2)中去。 最后剩一个数据就正常弹出即可。
int myStackPop(MyStack* obj) {
Queue* empty = &obj->q1;
Queue* nonEmpty = &obj->q2;
if(QueueEmpty(&obj->q2)) {
empty = &obj->q2;
nonEmpty = &obj->q1;
}
//当不为空的队列把 N-1 个数据倒腾倒空的队列中去
while(QueueSize(nonEmpty) != 1) {
QueuePush(empty,QueueFront(nonEmpty));
QueuePop(nonEmpty);
}
int top = QueueFront(nonEmpty);
QueuePop(nonEmpty);
return top;
}
3. 获取栈顶元素
在整个模拟实现过程中,是可以知道整个过程除了pop,两个队列肯定是一个为空,一个不为空的。
所以,想要获取栈顶的元素,直接拿到不为空的队列的队尾元素即可。
int myStackTop(MyStack* obj) {
Queue* empty = &obj->q1;
Queue* nonEmpty = &obj->q2;
if(QueueEmpty(&obj->q2)) {
empty = &obj->q2;
nonEmpty = &obj->q1;
}
return nonEmpty->tail->data;
}
4. 栈空
栈空就是两个队列为空,那么整个栈就为空
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
5. 栈销毁
首先要销毁栈的两个队列,再去销毁栈
void myStackFree(MyStack* obj) {
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
}
6.队列的模拟实现代码
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
}Queue;
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* del = cur;
cur = cur->next;
free(del);
}
pq->head = pq->tail = NULL;
}
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
else
{
newnode->data = x;
newnode->next = NULL;
}
if (pq->tail == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* del = pq->head;
pq->head = pq->head->next;
free(del);
del = NULL;
}
pq->size--;
}
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL && pq->tail == NULL;
}
int QueueSize(Queue* pq)
{
assert(pq);
/*QNode* cur = pq->head;
int n = 0;
while (cur)
{
++n;
cur = cur->next;
}
return n;*/
return pq->size;
}