赞
踩
用"栈实现队列",力扣中一道oj题,可以帮助刚接触"栈"和"队列"的新手更好的理解栈和队列这两种结构.
题目来源于力扣:
题目链接:https://leetcode.cn/problems/implement-queue-using-stacks/
难度:简单
//模拟队列类型的声明
typedef struct {
ST stackpush; //用于模拟队列的 入队操作
ST stackpop; //用于模拟队列的 出队操作
} MyQueue;
这里是借助两个栈用于模拟队列.
①:stackpush
模拟队列的入队
②:stackpop
模拟队列的出队
该队列是由两个栈实现的,所以重点关注两个栈的初始化即可.
步骤:
//队列的初始化
MyQueue* myQueueCreate() {
//给队列开辟空间
MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
if(obj==NULL)
{
perror("obj malloc fail");
}
//一定要记得这里要初始化(别漏掉了哦)
InitST(&obj->stackpush);
InitST(&obj->stackpop);
return obj;
}
对于入队列的模拟实现很简单,只需要将数据压入栈(模拟入队列:stackpush
)即可.
void myQueuePush(MyQueue* obj, int x) {
assert(obj);
STPush(&obj->stackpush,x);
}
函数要求:
将队首元素出队,并且返回刚刚出队的队首元素.
模拟出队相对复杂一些.
stackpop
(模拟出队的栈)数据出队列到空时,里面是没有数据的,所以先判断stackpop
是否有数据.stackpop
的栈顶元素作为队首元素.stackpop
的栈顶元素作为队首元素,使用top
变量记录下来.(因为后面要执行出栈操作).top
变量.int myQueuePop(MyQueue* obj) { assert(obj); if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出队列的栈)为空,则向栈(stackpush模拟入队列的栈)要数据 { //下面循环结束的条件是不为空 while(!STEmpty(&obj->stackpush))//将数据从模拟入队列栈全部倒过来 { //将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出栈) STPush(&obj->stackpop,STTop(&obj->stackpush)); STPop(&obj->stackpush); } } int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素; STPop(&obj->stackpop); return top; }
当两个栈中都没有元素时,则队列为空.
//写法1
bool myQueueEmpty(MyQueue* obj) {
if(STEmpty(&obj->stackpush)&&STEmpty(&obj->stackpop))//如果都为空,则为空栈
{
return true;
}
else
return false;
}
//写法2.
bool myQueueEmpty(MyQueue* obj) {
return STEmpty(&obj->stackpush) && STEmpty(&obj->stackpop);
}
stackpop
不为空时,则队首元素就是stackpop
的栈顶元素.stackpop
为空时,则队首元素就是stackpush
的栈底元素.int myQueuePeek(MyQueue* obj) {
assert(obj);
if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出队列)为空,则向栈(stackpush模拟入队列)要数据
{
while(!STEmpty(&obj->stackpush))
{
//将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出队列)
STPush(&obj->stackpop,STTop(&obj->stackpush));
STPop(&obj->stackpush);
}
}
int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素;
return top;
}
与myQueuePop
(出队列)函数比较,此函数只是将队首元素返回,并没有指向pop
出队操作.
所以我们在实现myQueuePop
函数时可以复用一下myQueuePeek
函数.
int myQueuePop(MyQueue* obj) {
int top=myQueuePeek(obj);
STPop(&obj->stackpop);
return top;
}
void myQueueFree(MyQueue* obj) {
STDestory(&obj->stackpush);
STDestory(&obj->stackpop);
free(obj);
}
前面的代码是栈的实现,由于c语言不能像c++那样直接调用库.
typedef int stacktype; typedef struct stack//定义栈的类型 { stacktype* data; int top; int capacaity; }ST; void InitST(ST* ps);//初始化栈 void STPush(ST* ps, stacktype x);//压栈 void STPop(ST* ps);//出栈 bool STEmpty(ST* ps);//判断是否为空栈 stacktype STTop(ST* ps);//返回栈顶元素 void STDestory(ST* ps);//栈的销毁 void InitST(ST* ps)//初始化栈 { assert(ps); ps->top = -1; ps->capacaity = 4; ps->data = (stacktype*)malloc(ps->capacaity * sizeof(stacktype)); } void STPush(ST* ps, stacktype x)//压栈 { assert(ps); if (ps->top+1 == ps->capacaity) { ps->capacaity *= 2; ST* tmp = (stacktype*)realloc(ps->data, ps->capacaity * sizeof(stacktype)); if(tmp == NULL) { printf("增容失败\n"); } ps->data = tmp; } ps->top++; ps->data[ps->top] = x; } void STPop(ST* ps)//出栈 { assert(ps); assert(!STEmpty(ps)); ps->top--; } bool STEmpty(ST* ps)//判断是否为空栈,是空返回真 { assert(ps); if (ps->top == -1) { return true; } return false; } stacktype STTop(ST* ps)//返回栈顶元素 { assert(ps); return ps->data[ps->top]; } void STDestory(ST* ps)//销毁栈 { assert(ps); free(ps->data); ps->data = NULL; ps->top = -1; ps->capacaity = 0; } //模拟队列类型的声明 typedef struct { ST stackpush; ST stackpop; } MyQueue; //队列的初始化 MyQueue* myQueueCreate() { MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue)); if(obj==NULL) { perror("obj malloc fail"); } //一定要记得这里要初始化 InitST(&obj->stackpush); InitST(&obj->stackpop); return obj; } void myQueuePush(MyQueue* obj, int x) { assert(obj); STPush(&obj->stackpush,x); } int myQueuePop(MyQueue* obj) { assert(obj); if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出栈)为空,则向栈(stackpush模拟入栈)要数据 { while(!STEmpty(&obj->stackpush)) { //将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出栈) STPush(&obj->stackpop,STTop(&obj->stackpush)); STPop(&obj->stackpush); } } int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素; STPop(&obj->stackpop); return top; } bool myQueueEmpty(MyQueue* obj) { if(STEmpty(&obj->stackpush)&&STEmpty(&obj->stackpop))//如果都为空,则为空栈 { return true; } else return false; //return STEmpty(&obj->stackpush)&&STEmpty(&obj->stackpop); } int myQueuePeek(MyQueue* obj) { if(STEmpty(&obj->stackpop))//如果栈(stackpop模拟出栈)为空,则向栈(stackpush模拟入栈)要数据 { while(!STEmpty(&obj->stackpush)) { //将栈(stackpush模拟入队)的栈顶元素依次压入栈(stackpop模拟出栈) STPush(&obj->stackpop,STTop(&obj->stackpush)); STPop(&obj->stackpush); } } int top=STTop(&obj->stackpop);//记录用来模拟出队列的栈的栈顶元素; return top; //return STTop(&obj->stackpop); } void myQueueFree(MyQueue* obj) { STDestory(&obj->stackpush); STDestory(&obj->stackpop); free(obj); }
运行结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。