目录
前言
栈的特点是后进先出,而队列的特点是先进先出,如果要用栈实现队列的特点,这里可以用两个栈来实现,一个栈用于做入栈操作,另一个做出栈操作,在两个栈的配合下可以实现队列。
例如以下两个栈
要想实现队列的特点,就得让1先出来,但单个栈只会先让4出来,所以我们再定义一个栈让栈1的元素一个一个移动到栈2,再让栈2的元素出栈即可完成先进先出的操作。
栈的结构
用于实现队列的两个栈的结构,没有什么特别的要求
typedef struct {
int *stk;
int size;
int capacity;
}MyStack;
栈的基本操作
栈的创建初始化,入栈,出栈,判断栈是否为空等
//创建栈
MyStack* StackCreat(int capacity){
MyStack *ret=malloc(sizeof(MyStack));
ret->stk=malloc(sizeof(int)*capacity);
ret->size=0;
ret->capacity=capacity;
return ret;
}
//入栈
void StackPush(MyStack* obj,int x){
obj->stk[obj->size++]=x;
}
//出栈
void StackPop(MyStack* obj){
obj->size--;
}
//栈顶
int StackTop(MyStack* obj){
return obj->stk[obj->size-1];
}
//判断栈空
int Stackempty(MyStack* obj){
return obj->size==0;
}
//销毁栈
void StackFree(MyStack* obj){
free(obj->stk);
}
队列的结构
队列包含两个栈
typedef struct {
MyStack *Instack;
MyStack *Outstack;
} MyQueue;
队列的初始化
MyQueue* myQueueCreate() {
MyQueue *ret=malloc(sizeof(MyStack));
ret->Instack=StackCreat(100);//这里每个栈容量为100
ret->Outstack=StackCreat(100);
return ret;
}
循环出栈
我们需要一个循环出栈的操作,将栈1的元素全部搬移到栈2
//循环出栈
void in_out(MyQueue* ret){
while(!Stackempty(ret->Instack)){
StackPush(ret->Outstack,StackTop(ret->Instack));
StackPop(ret->Instack);
}
}
入队
入队只需要做入栈操作即可
void myQueuePush(MyQueue* obj, int x) {
StackPush(obj->Instack,x);
}
出队
将栈1的元素搬移到栈2的操作需要有一个前提:栈2为空。如果栈2不为空则需要先把栈2的所有元素全部出栈后才能进行搬移操作
int myQueuePop(MyQueue* obj) {//出队
if(Stackempty(obj->Outstack)){
in_out(obj);
}
int a=StackTop(obj->Outstack);
//StackPop(obj->Outstack);
obj->Outstack->size--;
return a;
}
返回队头
也就是栈2的栈顶元素
int myQueuePeek(MyQueue* obj) {//返回队头
if(Stackempty(obj->Outstack)){
in_out(obj);
}
return StackTop(obj->Outstack);
}
判断队列是否为空
bool myQueueEmpty(MyQueue* obj) {
if(Stackempty(obj->Instack) && Stackempty(obj->Outstack))
return true;
return false;
}
销毁队列
void myQueueFree(MyQueue* obj) {
StackFree(obj->Instack);
StackFree(obj->Outstack);
}