目录
前言
我们已经了解队列和栈的区别,队列的特点是先进先出,而栈是先进后出,我们能否用队列来实现栈的特征呢,当然是可以的,我们需要两个队列来实现,实现入栈操作时只需要选择一个队列正常入队即可,出栈时则需要把不为空的队列的前N-1个元素全部转移到另一个队列,再将剩下的一个元素出队即可。
例如以下俩队列组成的栈,出栈时我们需要把4移出,但单个队列只能现将1移出然后再移出后面的元素
所以我们需要现将队列1里的前N-1个元素(也就是3个)先移动到队列2里,然后再把剩下的一个元素(4)移出即可
队列的结构
实现栈所用的两个队列采用循环队列最佳,队列结构如下
typedef struct queue{
int* data;
int front;
int rear;
int size;
}Queue;
栈的结构
typedef struct {
Queue *queue1,*queue2;//一个栈里包含两个队列
} MyStack;
循环队列基本操作
循环队列的初始化、入队、出队以及判断队列是否为空
//初始化队列
Queue *InitQueue(int x){
Queue *obj=(Queue*)malloc(sizeof(Queue));
obj->data=(int *)malloc(sizeof(int)*x);
obj->front=-1;
obj->rear=-1;
obj->size=x;
return obj;
}
//入队
void QueuePush(Queue *obj,int x){
if(obj->front==-1){
obj->front=0;
}
obj->rear=(obj->rear+1) % obj->size;
obj->data[obj->rear]=x;
}
//出队
int QueuePop(Queue *obj){
int a=obj->data[obj->front];
if(obj->front==obj->rear){
obj->front=-1;
obj->rear=-1;
return a;
}
obj->front=(obj->front+1)%obj->size;
return a;
}
//判断队空
int Isempty(Queue *obj){
return obj->front==-1;
}
栈的初始化
MyStack* myStackCreate() {//创建
MyStack *obj=(MyStack*)malloc(sizeof(MyStack));
obj->queue1=InitQueue(20);//这里初始化每个队列的容量为20
obj->queue2=InitQueue(20);
return obj;
}
入栈
void myStackPush(MyStack* obj, int x) {//入栈
if(Isempty(obj->queue1)){
QueuePush(obj->queue2,x);
}else{
QueuePush(obj->queue1,x);
}
}
出栈
int myStackPop(MyStack* obj) {//出栈
if(Isempty(obj->queue1)){
while(obj->queue2->front!=obj->queue2->rear){
QueuePush(obj->queue1,QueuePop(obj->queue2));
}
return QueuePop(obj->queue2);
}
while(obj->queue1->front!=obj->queue1->rear){
QueuePush(obj->queue2,QueuePop(obj->queue1));
}
return QueuePop(obj->queue1);
}
栈顶
和出栈相似,但没有移出栈里的数据
int myStackTop(MyStack* obj) {//栈顶
if(Isempty(obj->queue1)){
return obj->queue2->data[obj->queue2->rear];
}
return obj->queue1->data[obj->queue1->rear];
}
判断栈是否为空
bool myStackEmpty(MyStack* obj) {//判断是否为空
if(Isempty(obj->queue1) && Isempty(obj->queue2))
return true;
return false;
}
栈的销毁
void myStackFree(MyStack* obj) {//销毁
free(obj->queue1->data);
obj->queue1->data=NULL;
free(obj->queue2->data);
obj->queue2->data=NULL;
free(obj->queue1);
obj->queue1=NULL;
free(obj->queue2);
obj->queue2=NULL;
free(obj);
obj=NULL;
}