题目来自力扣,具体的要求如下:
目录
思路
首先需要开辟两个个栈,因为栈的性质是先入后出,所以需要一个栈专门入数据,另一个栈专门出数据,这样就实现了先入先出的队列。
1、初始化队列
MyQueue* myQueueCreate() {
MyQueue * que=(MyQueue *)malloc(sizeof(MyQueue));
if(que==NULL)
{
printf("malloc is fail");
exit(-1);
}
StackInit(&que->st1);
StackInit(&que->st2);
return que;
}
2、入队列
经过分析可知,只需要入第一个栈即可。
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->st1, x);
}
3、出队列
因为要按照先入先出的原则出队列,所以第二个栈是专门用来出队列的,但是必须要确保第一个栈是空的,即要先把第一个栈的数据导入到第二个栈中。
int myQueuePop(MyQueue* obj) {
if(StackEmpty(&obj->st2))
{
while(!StackEmpty(&obj->st1)) //如果st1不为空
{
StackPush(&obj->st2, StackTop(&obj->st1));
StackPop(&obj->st1);
}
}
int ret=StackTop(&obj->st2);
StackPop(&obj->st2);
return ret;
}
4、队列开头的元素
在此我们需要思考队列开头的元素在哪个位置,假设一个队列是1,2,3,4,5,那么这个队列的头元素是1,此时队列的的数据就存放在第一个数据栈中。由栈的特性可知,我们是不能返回数据栈中的第一个元素,所以只能参照出队列的思路,将数据栈的元素导入到出栈中,然后返回出栈的元素即可。
int myQueuePeek(MyQueue* obj) {
if(StackEmpty(&obj->st2)) // 如果st2 为空 就把st1的数据倒过来
{
while(!StackEmpty(&obj->st1)) //如果st1不为空
{
StackPush(&obj->st2, StackTop(&obj->st1));
StackPop(&obj->st1);
}
}
int ret=StackTop(&obj->st2);
return ret;
}
5、判断空队列
要同时判断两个栈中是否为空。
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->st1)&&StackEmpty(&obj->st2);
}
6、队列销毁
先销毁俩个栈,然后释放开辟出队列的指针。
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->st1);
StackDestroy(&obj->st2);
free(obj);
}
附:栈的操作:
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top; // 栈顶
int capacity; // 容量
}Stack;
// 初始化栈
void StackInit(Stack* ps);
// 入栈
void StackPush(Stack* ps, STDataType data);
// 出栈
void StackPop(Stack* ps);
// 获取栈顶元素
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);
// 初始化栈
void StackInit(Stack* ps)
{
ps->a = NULL;
ps->capacity = ps->top = 0;
}
// 入栈
void StackPush(Stack* ps, STDataType data)
{
//先扩容
if (ps->capacity == ps->top)
{
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* temp = (STDataType*) realloc (ps->a, sizeof(STDataType) * newcapacity);
if (temp == NULL)
{
printf("realloc is fail\n");
exit(-1);
}
ps->a = temp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = data;
ps->top++;
}
// 出栈
void StackPop(Stack* ps)
{
assert(!StackEmpty( ps));
ps->top--;
// 销毁栈 )
}
// 获取栈顶元素
STDataType StackTop(Stack* ps)
{
assert(!StackEmpty(ps));
return ps->a[ps->top-1];
}
// 获取栈中有效元素个数
int StackSize(Stack* ps)
{
return ps->top;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(Stack* ps)
{
return ps->top == 0;
}
// 销毁栈
void StackDestroy(Stack* ps)
{
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
typedef struct {
Stack st1;
Stack st2;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue * que=(MyQueue *)malloc(sizeof(MyQueue));
if(que==NULL)
{
printf("malloc is fail");
exit(-1);
}
StackInit(&que->st1);
StackInit(&que->st2);
return que;
}
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->st1, x);
}
int myQueuePop(MyQueue* obj) {
if(StackEmpty(&obj->st2))
{
while(!StackEmpty(&obj->st1)) //如果st1不为空
{
StackPush(&obj->st2, StackTop(&obj->st1));
StackPop(&obj->st1);
}
}
int ret=StackTop(&obj->st2);
StackPop(&obj->st2);
return ret;
}
int myQueuePeek(MyQueue* obj) {
if(StackEmpty(&obj->st2)) // 如果st2 为空 就把st1的数据倒过来
{
while(!StackEmpty(&obj->st1)) //如果st1不为空
{
StackPush(&obj->st2, StackTop(&obj->st1));
StackPop(&obj->st1);
}
}
int ret=StackTop(&obj->st2);
return ret;
}
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->st1)&&StackEmpty(&obj->st2);
}
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->st1);
StackDestroy(&obj->st2);
free(obj);
}