⭐️ 题目描述
🌟 leetcode链接:用队列实现栈
1️⃣ 思路和图解:
push:
入栈操作只需要往不为空的队列入数据即可,如果都为空,其中任意一个队列都可以。
void myStackPush(MyStack* obj, int x) {
// 往有数据的队列中入数据(模拟入栈)
// q1队列不为空 则往q1队列入数据
if (!QueueIsEmpty(&obj->q1)) {
QueuePush(&obj->q1 , x);
// printf("%d " , QueueFront(&obj->q1));
} else {
QueuePush(&obj->q2 , x);
printf("%d " , QueueBack(&obj->q2));
}
}
pop:
出栈操作需要把有数据的队列依次出数据,直到只剩下一个元素的时候,再依次把出队列的数据入到另一个队列中,在把刚才出数据的那个队列的最后一个元素删除即可。
int myStackPop(MyStack* obj) {
// 两个队列为空即栈为空 不需要删除
if (myStackEmpty(obj)) {
return -1;
}
Queue *emptyQueue = &obj->q1;
Queue *noneEmptyQueue = &obj->q2;
if (!QueueIsEmpty(&obj->q1)) {
noneEmptyQueue = &obj->q1;
emptyQueue = &obj->q2;
}
// 把有数据的队列对头数据 push 到没有数据的队列
// 只剩一个数据的时候 循环结束 删除仅剩的一个元素(模拟出栈)
while (QueueSize(noneEmptyQueue) > 1) {
QueuePush(emptyQueue , QueueFront(noneEmptyQueue));
QueuePop(noneEmptyQueue);
}
// 删除仅剩的一个元素(模拟出栈)
QueueDataType popTopElement = QueueFront(noneEmptyQueue);
QueuePop(noneEmptyQueue);
return popTopElement;
}
top:
返回栈顶元素,把不为空的队列中队尾的数据取出即可。
int myStackTop(MyStack* obj) {
// 两个队列为空即栈为空 没有栈顶元素可取
if (myStackEmpty(obj)) {
return -1;
}
// 若 q1 队列不为空 则返回 q1 队列队尾数据(模拟取栈顶元素),否则相反
return !QueueIsEmpty(&obj->q1) ? QueueBack(&obj->q1) : QueueBack(&obj->q2);
}
empty:
两个队列都为空,则栈为空。
bool myStackEmpty(MyStack* obj) {
// 空返回真 非空返回假
// 两个队列都为空 则栈为空
return QueueIsEmpty(&obj->q1) && QueueIsEmpty(&obj->q2);
}
其余接口:
// 创建两个队列 用来模拟实现栈
typedef struct {
Queue q1;
Queue q2;
} MyStack;
// 使用两个队列创建栈
MyStack* myStackCreate() {
// 为栈创建空间
MyStack* stack = (MyStack*)malloc(sizeof(MyStack));
// 初始化两个队列
QueueInit(&stack->q1);
QueueInit(&stack->q2);
return stack;
}
void myStackFree(MyStack* obj) {
// 先销毁两个队列
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
}