题目描述
题目链接:225. 用队列实现栈 - 力扣(LeetCode)
题目分析
我们先把之前写的队列实现代码搬过来
用队列实现栈最主要的是实现栈后进先出的特点,而队列的特点是先进先出,那么我们可以用两个队列来实现
- 一个队列存数据
- 另一个队列在出数据的时候导数据
具体的接口有下面几个
初始化
我们先创建一个结构体来封装两个队列
初始化两个队列
销毁
我们要分析清楚这个结构,pst存q1,q2两个队列,需要先销毁q1和q2,然后释放pst
入栈
入栈我们入到不为空的队列中去,当q1不为空则入队列q1,否则入队列q2
出栈
出栈的时候就需要导数据了,比如数据都在q1中,q2为空,这时我们先判断空队列是哪一个,然后将非空队列前n-1个数据导入到空队列中,最后留一个数据就是栈顶数据,也是队列的队头数据,可以用QFront接口,先用top保存这个数据,接着pop掉这个数据,返回top
判空
返回栈顶元素
直接取不为空队列的队尾数据
代码示例
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
//创建
typedef int QDataType;
typedef struct QueueNode
{
QDataType val;
struct QueueNode* next;
}QNode;
typedef struct Queue
{
QNode* phead;
QNode* ptail;
int size;
}Queue;
//把队列的头尾封装在一个结构体中
//初始化
void QInit(Queue* pq);
//销毁
void QDestroy(Queue* pq);
//入队列
void QPush(Queue* pq, QDataType x);
//出队列
void QPop(Queue* pq);
//取队头数据
QDataType QFront(Queue* pq);
//取队尾数据
QDataType QBack(Queue* pq);
//判空
bool QEmpty(Queue* pq);
//返回队列有效元素个数
int QSize(Queue* pq);
//初始化
void QInit(Queue* pq)
{
assert(pq);
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
//销毁
void QDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->phead;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->phead = pq->ptail = NULL;
pq->size = 0;
}
//入队列
void QPush(Queue* pq, QDataType x)
{
assert(pq);
//创建newnode
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
return;
}
newnode->val = x;
newnode->next = NULL;
if (pq->ptail == NULL)
{
pq->phead = pq->ptail = newnode;
}
else
{
pq->ptail->next = newnode;
pq->ptail = newnode;
}
pq->size++;
}
//出队列
void QPop(Queue* pq)
{
assert(pq);
assert(pq->phead);
QNode* del = pq->phead;
pq->phead = pq->phead->next;
free(del);
del = NULL;
if (pq->phead == NULL)
{
pq->ptail = NULL;
//防止ptail成为野指针
}
pq->size--;
}
//取队头数据
QDataType QFront(Queue* pq)
{
assert(pq);
assert(pq->phead);
return pq->phead->val;
}
//取队尾数据
QDataType QBack(Queue* pq)
{
assert(pq);
assert(pq->ptail);
return pq->ptail->val;
}
//判空
bool QEmpty(Queue* pq)
{
assert(pq);
return pq->phead == NULL;
}
//返回队列有效元素个数
int QSize(Queue* pq)
{
assert(pq);
return pq->size;
}
typedef struct MyStack{
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* pst = (MyStack*)malloc(sizeof(MyStack));
QInit(&(pst->q1));
QInit(&(pst->q2));
return pst;
}
void myStackPush(MyStack* obj, int x) {
if (!QEmpty(&(obj->q1)))
{
QPush(&(obj->q1), x);
}
else
{
QPush(&(obj->q2), x);
}
}
int myStackPop(MyStack* obj) {
Queue* empty = &(obj->q1);
Queue* nonempty = &(obj->q2);
if (!QEmpty(&(obj->q1)))
{
empty = &(obj->q2);
nonempty = &(obj->q1);
}
while (QSize(nonempty) > 1)
{
QPush(empty, QFront(nonempty));
QPop(nonempty);
}
int top = QFront(nonempty);
QPop(nonempty);
return top;
}
int myStackTop(MyStack* obj) {
if (!QEmpty(&(obj->q1)))
{
return QBack(&(obj->q1));
}
else
{
return QBack(&(obj->q2));
}
}
bool myStackEmpty(MyStack* obj) {
return QEmpty(&(obj->q1)) && QEmpty(&(obj->q2));
}
void myStackFree(MyStack* obj) {
QDestroy(&(obj->q1));
QDestroy(&(obj->q2));
free(obj);
}