栈——先进后出
队列——先进先出
本文将利用两个栈实现一个队列的功能。
关于队列的基本函数可以参考这篇——栈
1.基本数据类型
typedef struct {
//一个用来push
ST s_push;
//另一个用来pop
ST s_pop;
} MyQueue;
2.创建队列
malloc队列结构体MyQueue,并对两个栈进行初始化。
MyQueue* myQueueCreate() {
//malloc
MyQueue* OBJ = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&OBJ->s_pop);
StackInit(&OBJ->s_push);
return OBJ;
}
3.入队
将入队的数字,直接压栈到s_push栈
中。
void myQueuePush(MyQueue* obj, int x) {
//入队 直接压入到s_push栈中
assert(obj);
StackPush(&obj->s_push,x);
}
栈空间是动态分配的,直接压就行。
4.出队
首先两个栈都不为空。
如果s_pop栈不为空,将s_pop出栈,否则将s_push栈中的元素全部转移到s_pop中,最后将s_pop出栈。
int myQueuePop(MyQueue* obj) {
//出队 看s_pop是否为空,不空s_pop直接弹栈
//如果s_pop为空,将s_push的元素全部出栈,再入栈到s_pop中去,再将s_pop弹栈
assert(obj);
assert((!StackEmpty(&obj->s_pop)) || (!StackEmpty(&obj->s_push)));
if (StackEmpty(&obj->s_pop))
{
while (StackSize(&obj->s_push) > 0)
{
StackPush(&obj->s_pop, StackTop(&obj->s_push));//获取s_push栈顶,压入s_pop栈
StackPop(&obj->s_push);
}
}
STDataType x = StackTop(&obj->s_pop);
StackPop(&obj->s_pop);//弹栈
return x;
}
5.获取队头元素
逻辑与4相同,只需获取s_pop的栈顶元素无需弹栈
int myQueuePeek(MyQueue* obj) {
//获取队头元素
assert(obj);
assert((!StackEmpty(&obj->s_pop)) || (!StackEmpty(&obj->s_push)));
if (StackEmpty(&obj->s_pop))
{
while (StackSize(&obj->s_push) > 0)
{
StackPush(&obj->s_pop, StackTop(&obj->s_push));//获取s_push栈顶,压入s_pop栈
StackPop(&obj->s_push);
}
}
return StackTop(&obj->s_pop);
}
6.判断队列是否为空
两个栈都为空则队列为空
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->s_pop) && StackEmpty(&obj->s_push);
}
7.销毁队列
先将两个栈的空间free掉,再将obj这个队列结构free掉
void myQueueFree(MyQueue* obj) {
assert(obj);
StackDestroy(&obj->s_push);
StackDestroy(&obj->s_pop);
free(obj);
}
8.代码全貌
//****************************************************栈的实现
typedef int STDataType;
typedef struct ST
{
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);//弹栈
//当前栈的大小
int StackSize(ST* ps);
//获取栈顶元素
STDataType StackTop(ST* ps);
//栈是否为空
bool StackEmpty(ST* ps);
//初始化
void StackInit(ST* ps)
{
assert(ps);
ps->a=NULL;
ps->top=ps->capacity=0;
}
//压栈
void StackPush(ST* ps,STDataType x)
{
assert(ps);
if(ps->top==ps->capacity)//栈满需扩容
{
int newcapacity=(ps->capacity==0)?4:2*ps->capacity;
STDataType* newspace=(STDataType*)realloc(ps->a,newcapacity*sizeof(STDataType));
assert(newspace);
ps->a=newspace;
ps->capacity=newcapacity;
}
ps->a[ps->top]=x;
ps->top++;
}
//出栈
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
//判断栈是否为空
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top==0;
}
//栈的大小
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
//获取栈顶元素
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top-1];
}
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->top=ps->capacity=0;
}
//****************************************************队列的实现
typedef struct {
//需要两个栈
//一个用来push
ST s_push;
//另一个用来pop
ST s_pop;
} MyQueue;
/** Initialize your data structure here. */
MyQueue* myQueueCreate() {
//malloc
MyQueue* OBJ = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&OBJ->s_pop);
StackInit(&OBJ->s_push);
return OBJ;
}
/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, int x) {
//入队 直接压入到s_push栈中
assert(obj);
StackPush(&obj->s_push,x);
}
/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {
//出队 看s_pop是否为空,不空s_pop直接弹栈
//如果s_pop为空,将s_push的元素全部出栈,再入栈到s_pop中去,再将s_pop弹栈
assert(obj);
assert((!StackEmpty(&obj->s_pop)) || (!StackEmpty(&obj->s_push)));
if (StackEmpty(&obj->s_pop))
{
while (StackSize(&obj->s_push) > 0)
{
StackPush(&obj->s_pop, StackTop(&obj->s_push));//获取s_push栈顶,压入s_pop栈
StackPop(&obj->s_push);
}
}
STDataType x = StackTop(&obj->s_pop);
StackPop(&obj->s_pop);//弹栈
return x;
}
/** Get the front element. */
int myQueuePeek(MyQueue* obj) {
//获取队头元素
assert(obj);
assert((!StackEmpty(&obj->s_pop)) || (!StackEmpty(&obj->s_push)));
if (StackEmpty(&obj->s_pop))
{
while (StackSize(&obj->s_push) > 0)
{
StackPush(&obj->s_pop, StackTop(&obj->s_push));//获取s_push栈顶,压入s_pop栈
StackPop(&obj->s_push);
}
}
return StackTop(&obj->s_pop);
}
/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->s_pop) && StackEmpty(&obj->s_push);
}
void myQueueFree(MyQueue* obj) {
assert(obj);
StackDestroy(&obj->s_push);
StackDestroy(&obj->s_pop);
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);
*/
青山不改 绿水长流