解题思路
数据结构中我们知道,队列的特点是先入先出。
本题可以使用两个栈实现,一个栈进行入队操作,另一个栈进行出队操作。
出队操作:当出队的栈不为空时,直接进行出栈操作;如果为空,需要把入队的栈元素全部到日出队的栈,然后再进行出栈操作。
图解分析
- push 1,2, 3,4
- pop 出队头元素,即1
因为此时pop栈是空,就需要把push栈中的元素全部导入到pop栈中。
队列结构
由于OJ函数,要求队列在堆区开辟。所以队列结构为如下所示,这里我们使用 顺序表实现栈。
补充:对于栈,数组实现和链表实现都可以。链表实现的情况,使用头插法更加方便。
题解
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
// 栈初始化 指针传递
void StackInit(ST* ps);
// 栈销毁
void StackDestroy(ST* ps);
// 压栈
void StackPush(ST* ps, STDataType x);
// 弹栈
void StackPop(ST* ps);
// 取栈顶元素
STDataType StackTop(ST* ps);
// 判断栈空
bool StackEmpty(ST* ps);
// 栈大小
int StackSize(ST* ps);
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
// top=0: top指向栈顶元素下一个位置
ps->top = 0;
ps->capacity = 0;
}
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
void StackPush(ST* ps, STDataType x)
{
assert(ps);
// 空间不够扩容
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newcapacity);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
void StackPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
typedef struct {
ST pushST;
ST popST;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&q->pushST);
StackInit(&q->popST);
return q;
}
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->pushST, x);
}
int myQueuePop(MyQueue* obj) {
// popST是空 先从pushST得到数
// popST 中符合先入先出的规则
if(StackEmpty(&obj->popST))
{
while(!StackEmpty(&obj->pushST))
{
StackPush(&obj->popST, StackTop(&obj->pushST));
StackPop(&obj->pushST);
}
}
int ret = StackTop(&obj->popST);
StackPop(&obj->popST);
return ret;
}
int myQueuePeek(MyQueue* obj) {
// 返回队列开头的元素
if(StackEmpty(&obj->popST))
{
while(!StackEmpty(&obj->pushST))
{
StackPush(&obj->popST, StackTop(&obj->pushST));
StackPop(&obj->pushST);
}
}
return StackTop(&obj->popST);
}
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);
}
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->popST);
StackDestroy(&obj->pushST);
free(obj);
}
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* int param_2 = myQueuePop(obj);
* int param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/