题目
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/implement-stack-using-queues
核心思路
1.栈特点先进后出,队列特点先进先出
2.自己实现队列
3.用两个队列实现栈
4.向栈插入数据时,如果两个队列都为空则随便选择一个插入数据,如果有一个不为空,则往不为空的队列上插入数据(每次都需要保证总有一个不为空)
5.删除栈顶数据时,把有不为空队列的前n-1个数据移向另一个空的队列,并删除最后一个未移除的数据
6.获取栈顶数据时,先判断哪个队列不为空,就把那个队列的队尾数据取出
7.判断栈是不是空时,只有两个队列皆空,栈才空
细节
这里肯定会有人疑惑为什么要保证队列其中一个不为空
如果两个队列都有数据,我们将不知道怎么入栈和出栈
1.入栈时,刚开始随机找一个队列
2.出栈时
我们要再想插入数据不为空的队列上入,由此可以看出不为空和为空的队列时刻在变化,所以我们每次插入和删除数据时都要判断
代码
typedef int QDateType;
typedef struct QueueNode
{
struct QueueNode* next;
QDateType data;
}QueueNode;
typedef struct Queue
{
QueueNode* head;
QueueNode* tail;
}Queue;
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDateType x);
void QueuePop(Queue* pq);
QDateType QueueFront(Queue* pq);
QDateType QueueBack(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = NULL;
pq->tail = NULL;
}
void QueueDestroy(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->head;
while (cur)
{
QueueNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = NULL;
pq->tail = NULL;
}
void QueuePush(Queue* pq, QDateType x)
{
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode == NULL)
{
printf("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
QueueNode* cur = pq->head->next;
free(pq->head);
pq->head = cur;
if (pq->head == NULL)
{
pq->tail = NULL;
}
}
QDateType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
QDateType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
int QueueSize(Queue* pq)
{
assert(pq);
//assert(!QueueEmpty(pq));
int count = 0;
QueueNode* cur = pq->head;
while (cur)
{
count++;
cur = cur->next;
}
return count;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL;
}
//以上代码为队列实现部分
typedef struct
{
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate()
{
MyStack* st = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&st->q1);
QueueInit(&st->q2);
return st;
}
void myStackPush(MyStack* obj, int x)
{
assert(obj);
if (!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1, x);
}
else
{
QueuePush(&obj->q2, x);
}
}
int myStackPop(MyStack* obj)
{
assert(obj);
Queue* empty = &obj->q1;
Queue* nonempty = &obj->q2;
if (!QueueEmpty(&obj->q1))
{
empty = &obj->q2;
nonempty = &obj->q1;
}
while (QueueSize(nonempty) > 1)
{
QueuePush(empty, QueueFront(nonempty));
QueuePop(nonempty);
}
int top = QueueFront(nonempty);
QueuePop(nonempty);
return top;
}
int myStackTop(MyStack* obj)
{
assert(obj);
if (!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj)
{
assert(obj);
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj)
{
assert(obj);
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
obj = NULL;
}