232. 用栈实现队列 - 力扣(LeetCode) (leetcode-cn.com)
在答题之前,我们先把之前写的栈函数都拿过来用,我看C++代码几十行写完我写了一大堆,泪目
typedef int STDataType;
typedef struct Stack
{
STDataType* arr;
int top;
int capacity;
}Stack;
void StackInit(Stack* ps)
{
assert(ps);
ps->arr = NULL;
ps->capacity = 0;
ps->top = 0;
}
void StackPush(Stack* ps, STDataType data)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : (ps->capacity) * 2;
ps->arr = (Stack*)realloc(ps->arr, sizeof(Stack)* newcapacity);
if (ps->arr == NULL)
{
printf("realloc fail\n");
exit(-1);
}
ps->capacity = newcapacity;
}
ps->arr[ps->top++] = data;
}
void StackPop(Stack* ps)
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
STDataType StackTop(Stack* ps)
{
assert(ps);
return ps->arr[ps->top-1];
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->top;
}
int StackEmpty(Stack* ps)
{
assert(ps);
return ps->top == 0;
}
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->arr);
ps->arr = NULL;
ps->top = 0;
ps->capacity = 0;
}
正式开始答题;
初始化并返回创建好的指针
我们先创建好结构体,结构体里面有两个栈:
typedef struct {
Stack s1;
Stack s2;
} MyQueue;
然后我们还是判断一下是否为空
初始化还是用我们的栈初始化函数即可
MyQueue* myQueueCreate()
{
MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
assert(obj);
StackInit(&obj->s1);
StackInit(&obj->s2);
return obj;
}
将元素X推入队列的末尾
我们知道栈是先进后出,而队列是先进先出,假设现在有 1 2 3 4 四个元素要进队列,我们将其全部尾插到 s1 里面:
void myQueuePush(MyQueue* obj, int x)
{
assert(obj);
StackPush(&obj->s1, x);
}
返回队列开头元素并将其移除
我们知道现在全部元素都在s1里面,我们最好判断一下:
第一种情况:
s1有元素,s2为空,我们将s1的元素压到s2里面,因为是栈,所以每次操作都是从尾部(图里从右向左)
压s2就变成了:
我们最后再把s1里面的删掉,返回s2最后的值即可;
第二种情况:
如果s2里面已经有元素,那我们直接返回即可;
int myQueuePop(MyQueue* obj)
{
assert(obj);
if (StackEmpty(&obj->s2))
{
while (!StackEmpty(&obj->s1))
{
StackPush(&obj->s2, StackTop(&obj->s1));
StackPop(&obj->s1);
}
int data = StackTop(&obj->s2);
StackPop(&obj->s2);
return data;
}
int data = StackTop(&obj->s2);
StackPop(&obj->s2);
return data;
}
返回队列开头的元素;
同样,如果s2里面有元素,我们就返回s2尾部,但如果s2为空。那就返回s1,这里要注意:
s2的尾部是s1的头,如果s2为空,那我们返回s1的位置就应该是s1数组下标为0的位置
比方说:压进去 1 2 3 4
上面我们的操作是把s1的值压到s2里面,根据图示,1的位置是s2的尾部和s1的头,一定注意
看栈是否为空;
判断obj里面的s1 和 s2 即可:
bool myQueueEmpty(MyQueue* obj)
{
return StackEmpty(&obj->s1) && StackEmpty(&obj->s2);
}
释放栈:
void myQueueFree(MyQueue* obj)
{
assert(obj);
StackDestroy(&obj->s1);
StackDestroy(&obj->s2);
}