栈实现队列
相似的题目:【LeetCode.队列.225】用队列实现栈
感兴趣
的朋友可以顺便也看看!
文章目录
一、题目
二、题目分析
首先把栈和队列都摆出来慢慢看
队列进入是1、2、3
,出队列也应该是1、2、3
而栈进入是1、2、3
,我们现在要控制出去也是1、2、3
将一个栈里的元素拿到另外一个栈里,再从这个栈里出来
这就是按照队列的方式了
力扣上有很多个接口
我们一个一个写
我们还需要很多栈的接口(因为是c语言): 【数据结构】栈_Rinne’s blog-CSDN博客
1. 准备好栈
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;//栈
2. 初始化队列
我们的队列是由两个栈形成的
所以队列的成员构成中有两个队列,一个是用来出队,一个是用来入队
typedef struct {
ST PushST;
ST PopST;
} MyQueue;//队列,含两个栈
//初始化栈
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;//栈容量0
ps->top = 0;//栈顶还是0
}
//初始化栈构成的队列
MyQueue* myQueueCreate() {
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&q->PushST);
StackInit(&q->PopST);
return q;
}
3. 将元素 x 推到队列的末尾
放到专门入队的栈口,用到进栈的接口
//进栈
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
//满了需要扩容
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
//队列入队、入栈
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->PushST, x);
}
4. 返回队列开头的元素
分两种情况
情况1:出队的里面什么都没有
那么就把入队的依次push到出队
的栈中
再拿出出队的栈第一个元素
情况二:如果出队栈中有元素
按照情况一最后一步
处理
//判断栈是否为空
bool StackEmpty(ST* ps)
{
return ps->top == 0;
}
//出栈
void StackPop(ST* ps)
{
assert(ps);
ps->top--;
}
//找到栈顶
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
int myQueuePeek(MyQueue* obj) {
//先判断用来出队的栈里面有没有元素
if(StackEmpty(&obj->PopST))
{
//出队的栈为空,把入队所有放入出队的栈
while(!StackEmpty(&obj->PushST))
{
//找到push栈顶,放入pop
StackPush(&obj->PopST, StackTop(&obj->PushST));
//把push栈顶pop掉
StackPop(&obj->PushST);
}
}
//返回栈顶元素
return StackTop(&obj->PopST);
}
5. 从队列的开头移除并返回元素
在上面代码的基础上pop一下
//队列出队、出栈
int myQueuePop(MyQueue* obj) {
int ret = myQueuePeek(obj);
StackPop(&obj->PopST);
return ret;
}
6. 判断队列是否为空
两个栈都为空即队列为空
//判断队列是否为空
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->PushST) && StackEmpty(&obj->PopST);
}
7. 销毁队列
销毁两个栈,再把队列malloc
出来的地方free
掉
//销毁栈
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
//销毁队列
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->PushST);
StackDestroy(&obj->PopST);
free(obj);
}
三、代码汇总
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;//栈
typedef struct {
ST PushST;
ST PopST;
} MyQueue;//队列,含两个栈
//初始化栈
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;//栈容量0
ps->top = 0;//栈顶还是0
}
//初始化栈构成的队列
MyQueue* myQueueCreate() {
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&q->PushST);
StackInit(&q->PopST);
return q;
}
//进栈
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
//满了需要扩容
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
//队列入队、入栈
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->PushST, x);
}
//判断栈是否为空
bool StackEmpty(ST* ps)
{
return ps->top == 0;
}
//出栈
void StackPop(ST* ps)
{
assert(ps);
ps->top--;
}
//找到栈顶
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
int myQueuePeek(MyQueue* obj) {
//先判断用来出队的栈里面有没有元素
if(StackEmpty(&obj->PopST))
{
//出队的栈为空,把入队所有放入出队的栈
while(!StackEmpty(&obj->PushST))
{
//找到push栈顶,放入pop
StackPush(&obj->PopST, StackTop(&obj->PushST));
//把push栈顶pop掉
StackPop(&obj->PushST);
}
}
return StackTop(&obj->PopST);
}
//队列出队、出栈
int myQueuePop(MyQueue* obj) {
int ret = myQueuePeek(obj);
StackPop(&obj->PopST);
return ret;
}
//判断队列是否为空
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->PushST) && StackEmpty(&obj->PopST);
}
//销毁栈
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
//销毁队列
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->PushST);
StackDestroy(&obj->PopST);
free(obj);
}