队列和栈相互模拟是面试题中的经典题目,这里小编提供两种方法:一种是引用C++的STL静态库提供的#include <stack>和#include <queue>,另一种是自己动手写栈结构和队列结构
1.引用STL栈和队列
//思路:两个队列相互转换,进栈以空队列为目标,出栈以非空队列为目标(//队列:先进先出
//栈:后进先出 )
//进栈:以空队列为目标,设A为空队列,先将待进栈数据data插入A中,再将B队列数据压入A中,同时删除B中压入数据
void SPush(queue<int> &QA,queue<int> &QB,int data){
if(QA.empty()){//若QA为空队列,操作目标为QA
QA.push(data);
while(!QB.empty()){
QA.push(QB.front());
QB.pop();
}
}else if(QB.empty()){//若QB为空队列,操作目标为QB
QB.push(data);
while(!QA.empty()){
QB.push(QA.front());
QA.pop();
}
}
}
//出栈:以非空队列为目标,设B为非空队列,按照正常顺序输出B队列中的数据即可
void SPop(queue<int> &QA,queue<int> &QB,int &data){
if(!QB.empty()){//QB为非空队列,操作目标
data=QB.front();
QB.pop();
}else if(!QA.empty()){//若QA为非空队列,操作目标
data=QA.front();
QA.pop();
}
}
//栈模拟队列
//思路:以其中一个栈为入栈目标一个为出栈目标,假设SA为入栈目标,SB为出栈目标
//入队列:若SB中数据不为空,则先将SB中的数据先压入SA中,然后再将待压入数据压入SA中
void QPush(stack<int> &SA,stack<int> &SB,int data){
while(!SB.empty()){
SA.push(SB.top);
SB.pop();
}
SA.push(data);
}
//出队列:将SA中的数据压入SB栈中,同时删除SA中压入的数据,待SA的数据完全压入SB中后,从SB中取出的数据即可
void QPop(stack<int> &SA,stack<int> &SB,int &data){
while(!SA.empty()){
SB.push(SA.top());
SA.pop();
}
data=SB.top();
SB.pop();
}
2.自己动手写栈和队列结构
队列与栈
队列结构
Typedef int ElemType;
Typedef struct QueueNode{
ElemType data;
Struct LinkQueue *next;
}QueueNode,*QueueNodePre;
Typedef struct LinkQueue{
QueueNodePre front;
QueueNodePre rear;
};
栈结构
Const int MAXSIZE=100,INCREASEMENT=10;
Typedef struct Stack{
ElemType *base,*top;
Int stacksize;
};
队列模拟栈(队列先进先出,栈先进后出)
思路:使用两个队列A、B模拟一个栈,两个队列相互负责入栈操作,不固定化(注意与栈模拟队列区别);
进栈操作:取其中空队列为进栈操作目标,假设A为空,B存在元素,将待进栈的数据元素放入A队列中,然后将B中所有元素按顺序压入到A中,完成进栈操作;
出栈操作:取其中不为空队列为出栈操作目标,假设A为空,B存在元素,将B队列中数据元素按最先进来的在rear端,最后进的在front端排序,将B队列元素按正常取出(取front端)即可得到先进后出的栈方式取数据元素。
//进栈
Int Push(LinkQueue &QA,LinkQueue &QB,ElemType e){
If(!QA||!QB){
Return -1;
};
QueueNodePre p=(QueueNodePre)malloc(sizeof(QueueNode));
If(!p){
Return -1;
};
p->next=NULL;
P->data=e;
Int r=0;
If(QA.front==QA.rear){//QA目标操作队列
A.rear->next=p;
A.rear=p;
While(QB.rear!=QB.front){
R=DeleteLQueue(QB,e);
R=InsertLQueue(QA,e);
};
//如果允许使用库函数<queue> //queue <ElemType> QA,QB;
//While(!QB.empty()){
//E=QB.pop();
//QA.push(e);
//};
}else{
B.rear->next=p;
B.rear=p;
While(QA.rear!=QA.front){
R=DeleteLQueue(QA,e);
R=InsertLQueue(QB,e);
};
//如果允许使用库函数<queue> //queue<ElemType> QA,QB;
//While(!QA.empty()){
//E=QA.pop();
//QB.push(e);
//};
};
Return r;
};
//出栈
Int Pop(LinkQueue &QA,LinkQueue &QB,ElemType &e){
If(!QA||!QB){
Return -1;
};
Int r=0;
If(QA.rear==QA.front){//QB目标操作队列
If(QB.rear==QB.front){
Return -1;
};
R=DeleteLQueue(QB,e);
}else{
R=DeleteLQueue(QA,e);
};
Return r;
};
//队列插入元素
Int InsertLQueue(LinkQueue &Q,ElemType e){
If(!Q){
Return -1;
};
QueueNodePre p=(QueueuPre)malloc(sizeof(QueueNode));
If(!p){
Return -1;
};
P->data=e;
P->next=NULL;
Q.rear->next=p;
Q.rear=p;
Return 0;
};
//队列删除元素
Int DeleteLQueue(LinkQueue &Q,ElemType &e){
If(!Q||Q.rear==Q.front){
Return -1;
};
QueueNodePre p=Q.front->next;
E=p->data;
Q.front->next=p->next;
If(p==Q.rear){//改变尾指针
Q.rear=Q.front;
};
Free(p);
Return 0;
};
栈模拟队列(队列先进先出,栈先进后出)
思路:使用两个栈A和B模拟一个队列,一个栈专门负责入栈操作,固定化(注意与队列模拟栈区别),如栈A负责入栈操作,那么栈B就负责出栈操作;
进队列操作:以栈A为目标操作,先将栈B中的元素按顺序弹出,存入栈A,待所有栈B中的元素存入栈A后,最后再将新的元素添加到栈A中(与队列模拟栈相反);
出队列操作:以栈B为目标操作,先将栈A中所有元素顺序弹出,存入栈B,待所有栈A中的元素存入栈B后,最后再将栈B中栈顶的元素取出;
//队列插入元素
Int InsertLinkQueue(Stack &SA,Stack &SB,ElemType e){
If(!SA||!SB){
Return -1;
};
Int r=0;
ElemType e1;
While(SB.top!=SB.base){
R=Pop(SB,e1);
R=Push(SA,e1);
};
R=Push(SA,e);
Return r;
};
//队列删除元素
Int DeleteLinkQueue(Stack &SA,Stack &SB,ElemType &e){
If(!SA||!SB){
Return -1;
};
Int r=0;
ElemType e1;
While(SA.top!=SA.base){
R=Pop(SA,e1);
R=Push(SB,e1);
};
R=Pop(SB,e);
Return r;
};
//入栈
Int Push(Stack &S, ElemType e){
If(!S){
Return -1;
};
If(S.top-S.base>=S.stacksize){
S.base=(ElemType *)realloc(S.base,(S.stacksize+INCREASEMENT)*sizeof(ElemType));
If(!S.base){
Return -1;
};
S.top=S.base+S.stacksize;
S.stacksize+=INCREASEMENT;
};
*S.top++=e;
Return 0;
};
//出栈
Int Pop(Stack &S,ElemType &e){
If(!S||S.top==S.base){
Return -1;
};
E=*--S.top;
Return 0;
};