This article uses two stacks to implement queues
content
Implementing queues with stacks
Implementation Analysis of Queue
Queue definition and initialization
Returns the head element of the queue
Determine whether the queue is empty and the destruction of the queue
Question link: 232. Implementing Queues with Stacks - LeetCode (leetcode-cn.com)
Implementing queues with stacks
Implement a FIFO queue with two LIFO stacks.
Push 1 2 3 4 5
Pop 1 2 3 4 5
Writing the stack
The stack has the property of last-in-first-out. You can operate on the top of the stack. We use the sequence table to implement the stack. It has been implemented before, and we directly add the code:
typedef int Datatype;
typedef struct Stack
{
Datatype* a;
int top; //栈顶位置
int capacity; //容量
}ST;
void StackInit(ST* ps);
void StackDestory(ST* ps);
void StackPush(ST* ps,Datatype x);
void StackPop(ST* ps);
//判断栈是否为空
bool StackEmpty(ST* ps);
//数据个数
int StackSize(ST* ps);
//访问栈顶数据
Datatype StackTop(ST* ps);
//初始化
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
//销毁
void StackDestory(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
void StackPush(ST* ps, Datatype x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
ps->a = realloc(ps->a, newcapacity*sizeof(Datatype));
if (ps->a == NULL)
{
printf("realloc fail\n");
exit(-1);
}
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);
//if (ps->top > 0)
//{
// return false;
//}
//else
//{
// return true;
//}
return ps->top == 0;
}
//数据个数
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
//访问栈顶数据
Datatype StackTop(ST* ps)
{
assert(ps);
assert(ps->top>0);
return ps->a[ps->top-1];
}
Implementation Analysis of Queue
Two stacks implement queues, and two LIFO stacks are used to implement FIFO for a set of data.
Diagram:
Queue definition and initialization
It is still to open up space, determine whether it is successful, and then initialize the two stacks in the queue.
typedef struct {
ST Pushs1;
ST Pops2;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
assert(obj);
StackInit(&obj->Pushs1);
StackInit(&obj->Pops2);
return obj;
}
enqueue (push)
The stack is initialized, it has been empty, and it can be directly pushed into the stack
void myQueuePush(MyQueue* obj, int x) {
assert(obj);
StackPush(&obj->Pushs1,x);
}
dequeue (pop)
From the graphical analysis, you must first perform a data entry, and then pop the stack with data.
First determine whether the second stack is an empty stack, the empty stack can be poured, and then determine whether the first stack has elements.
Pour a top element of the stack into the empty stack, and pop the top element of the original stack, looping until the original stack is empty
Note: When pop is required to return the opposite element, the opposite element is the top element of the stack.
Then pop the top element of the stack.
int myQueuePop(MyQueue* obj) {
assert(obj);
//s2空时需要push进s1元素才能出
if(StackEmpty(&obj->Pops2))
{
while(!StackEmpty(&obj->Pushs1))
{
StackPush(&obj->Pops2,StackTop(&obj->Pushs1));
StackPop(&obj->Pushs1);
}
}
int front=StackTop(&obj->Pops2);
StackPop(&obj->Pops2);
return front;
}
Returns the head element of the queue
The head element of the queue is the top element of the non-empty stack after the data is poured once
After making a judgment and pouring, you can return directly.
int myQueuePeek(MyQueue* obj) {
assert(obj);
if(StackEmpty(&obj->Pops2))
{
while(!StackEmpty(&obj->Pushs1))
{
StackPush(&obj->Pops2,StackTop(&obj->Pushs1));
StackPop(&obj->Pushs1);
}
}
return StackTop(&obj->Pops2);
}
Determine whether the queue is empty and the destruction of the queue
There are also two stacks in the queue. The queue is empty only when the two stacks are empty. You can just return it directly.
When destroying, first destroy the two stacks, and then destroy the queue to prevent memory leaks.
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->Pushs1)&&StackEmpty(&obj->Pops2);
}
void myQueueFree(MyQueue* obj) {
StackDestory(&obj->Pushs1);
StackDestory(&obj->Pops2);
free(obj);
}