栈实现队列部分功能
OJ链接:https://leetcode.cn/problems/implement-queue-using-stacks/
这里我们要使用栈来实现队列的部分功能时,首先我们需要一个栈。
这里就让我们来当个cv工程师吧,毕竟C语言oj时还是需要手搓的。
栈
代码
typedef struct Stack
{
int* data;
int capacity;
int size;
}Stack;
void STpush(Stack* ST,int x);
void STinit(Stack* ST);
void STpop(Stack*ST);
void STbuyNode(Stack*ST)
{
int* ptr=(int*)malloc(sizeof(int)*20);
assert(ptr);
ST->data=ptr;
ST->capacity=20;
}
void STinit(Stack* ST)
{
STbuyNode(ST);
ST->size=-1;
};
void STpush(Stack* ST,int x)
{
if(ST->capacity==ST->size)
{
int*ptr=(int*)realloc(ST->data,sizeof(int)*ST->capacity*2);
assert(ptr);
ST->data=ptr;
ST->capacity*=2;
}
ST->size++;
ST->data[ST->size]=x;
}
void STpop(Stack*ST)
{
ST->data[ST->size]=0;
ST->size--;
}
这里当cv工程师还是很爽的。
接下来有了栈,就是如何用栈去实现对垒的功能了
typedef struct
{
} MyQueue;
void myQueueFree(MyQueue* obj);
bool myQueueEmpty(MyQueue* obj);
int myQueuePeek(MyQueue* obj);
int myQueuePop(MyQueue* obj);
void myQueuePush(MyQueue* obj, int x);
MyQueue* myQueueCreate();
即:
队列的创建
队列首元素访问
队列的插入
队列的数据删除
队列的判断是否为空
队列的销毁
我们都知道栈 是只进行栈顶的插入和删除数据
而队列则是 队首进行删除,队尾进行插入数据
当我们要用栈实现队列的插入操作时
直接在栈顶加入就行
但是当我们要用栈实现队列的删除时,问题就麻烦了
对于队列来说,需要进行删除的数据是栈底,而队列只能对栈顶数据进行的操作。
这个其实就是这个oj的核心问题,如果想清楚了,那整道题就迎刃而解了。
这里的思路就是,一个栈不行,那就两个栈来实现。
思路图:
设置两个栈,一个为添加栈,一个为删除栈,两个栈的元素进行相互处理,这样就可以实现队列的效果了。
队列的创建
typedef struct
{
Stack stack_del;
Stack stack_add;
} MyQueue;
MyQueue* myQueueCreate()
{
MyQueue*ptr=malloc(sizeof(MyQueue));
assert(ptr);
STinit(&ptr->stack_add);
STinit(&ptr->stack_del);
return ptr;
}
经过我们刚刚的分析,队列由插入栈和删除栈组成。
所以队列的定义是两个栈。
队列的判断空和销毁
bool myQueueEmpty(MyQueue* obj)
{
if(obj->stack_add.size==-1&&obj->stack_del.size==-1)
{
return true;
}
else
return false;
}
void myQueueFree(MyQueue* obj)
{
free(obj->stack_add.data);
free(obj->stack_del.data);
free(obj);
}
这里我们栈中的size初始值为-1,所以两个栈size都为-1时,则队列为空。
而free则是对队列的两个栈进行free,再将队列结构体进行置空
其实应该要将obj进行置空的,但是这个oj时接口型,所以就不管了。
队列的插入和删除
插入
void myQueuePush(MyQueue* obj, int x)
{
if (myQueueEmpty(obj)== true)
{
STpush(&obj->stack_add, x);
}
else
{
if(obj->stack_add.size == -1)
{
while (obj->stack_del.size != -1)
{
STpush(&obj->stack_add, obj->stack_del.data[obj->stack_del.size]);
STpop(&obj->stack_del);
}
}
STpush(&obj->stack_add, x);
}
}
首先对队列进行判空
如果为空
直接在插入栈进行数据插入就行。
当队列不为空时
如果插入栈不为空,则直接插入在插入栈
如果插入栈为空,则将删除栈的所有数移至插入栈,再进行插入。
删除
int myQueuePop(MyQueue* obj)
{
if(myQueueEmpty(obj)==true)
{
return NULL;
}
else
{
if(obj->stack_del.size==-1)
{
while(obj->stack_add.size!=-1)
{
STpush(&obj->stack_del,obj->stack_add.data[obj->stack_add.size]);
STpop(&obj->stack_add);
}
}
int x=obj->stack_del.data[obj->stack_del.size];
STpop(&obj->stack_del);
return x;
}
}
首先判断队列是否为空
队列为空
返回空
队列不为空
判断插入栈是否为空
为空,则直接对删除栈的数据进行出栈。
不为空,将插入栈的数据入栈至删除栈,再对删除栈,进行出栈。
整体代码
typedef struct Stack
{
int* data;
int capacity;
int size;
}Stack;
typedef struct
{
Stack stack_del;
Stack stack_add;
} MyQueue;
void myQueueFree(MyQueue* obj);
void STpush(Stack* ST,int x);
void STinit(Stack* ST);
void STpop(Stack*ST);
void myQueueFree(MyQueue* obj);
bool myQueueEmpty(MyQueue* obj);
int myQueuePeek(MyQueue* obj);
int myQueuePop(MyQueue* obj);
void myQueuePush(MyQueue* obj, int x);
MyQueue* myQueueCreate();
void STbuyNode(Stack*ST)
{
int* ptr=(int*)malloc(sizeof(int)*20);
assert(ptr);
ST->data=ptr;
ST->capacity=20;
}
void STinit(Stack* ST)
{
STbuyNode(ST);
ST->size=-1;
};
void STpush(Stack* ST,int x)
{
if(ST->capacity==ST->size)
{
int*ptr=(int*)realloc(ST->data,sizeof(int)*ST->capacity*2);
assert(ptr);
ST->data=ptr;
ST->capacity*=2;
}
ST->size++;
ST->data[ST->size]=x;
}
void STpop(Stack*ST)
{
ST->data[ST->size]=0;
ST->size--;
}
MyQueue* myQueueCreate()
{
MyQueue*ptr=malloc(sizeof(MyQueue));
assert(ptr);
STinit(&ptr->stack_add);
STinit(&ptr->stack_del);
return ptr;
}
void myQueuePush(MyQueue* obj, int x)
{
if (myQueueEmpty(obj)== true)
{
STpush(&obj->stack_add, x);
}
else
{
if(obj->stack_add.size == -1)
{
while (obj->stack_del.size != -1)
{
STpush(&obj->stack_add, obj->stack_del.data[obj->stack_del.size]);
STpop(&obj->stack_del);
}
}
STpush(&obj->stack_add, x);
}
}
int myQueuePop(MyQueue* obj)
{
if(myQueueEmpty(obj)==true)
{
return NULL;
}
else
{
if(obj->stack_del.size==-1)
{
while(obj->stack_add.size!=-1)
{
STpush(&obj->stack_del,obj->stack_add.data[obj->stack_add.size]);
STpop(&obj->stack_add);
}
}
int x=obj->stack_del.data[obj->stack_del.size];
STpop(&obj->stack_del);
return x;
}
}
int myQueuePeek(MyQueue* obj)
{
if(myQueueEmpty(obj)==true)
{
return NULL;
}
else
{
if(obj->stack_del.size==-1)
return obj->stack_add.data[0];
else
return obj->stack_del.data[obj->stack_del.size];
}
}
bool myQueueEmpty(MyQueue* obj)
{
if(obj->stack_add.size==-1&&obj->stack_del.size==-1)
{
return true;
}
else
return false;
}
void myQueueFree(MyQueue* obj)
{
free(obj->stack_add.data);
free(obj->stack_del.data);
free(obj);
}