两个栈实现队列:
(一)前提:
(1)栈的基本操作:
struct Stack
{
int top; //栈顶指针
int stacksize;//栈的大小
int *s; //栈底指针
};
void InitStack(Stack *s);
void Push(Stack *s, int k);
int Pop(*s);
int IsStackEmpty(*s);
int IsStackFull(*s);
(二)方法一:
(1)图解:
(2)解析:
1)入队列时,直接压到s1是就行了;
2)出队列时,先把s1中的元素全部出栈压入到s2中,弹出s2中的栈顶元素;再把s2的所有元素全部压回s1中。
(三)改进:
(1)解析:
1)入队:将元素压入s1。
2)出队:判断s2是否为空,如不为空,则直接弹出顶元素;如为空,则将s1的元素逐个“倒入”s2,把最后一个元素弹出并出队。
(2)代码实现:
//因为入队函数void enqueue(Queue q, int k);有两个参数,用两个栈实现一个
//队列,所以参数变成两个栈以及一个元素。
void EnQueue(Stack *s1, Stack *s2, int k)
{
Push(s1, k);
}
//出队列:参数由一个队列,变成两个栈。
int DeQueue(Stack *s1, Stack*s2)
{
if(IsStackEmpty(s2) == 1)//stack2为空,将stack1中所有元素压入stack2
{
while(IsStackEmpty(s1) == 0)
{
Push(s2, Pop(s1));
}
}
if(IsStackEmpty(s2) == 1)
//如果stack1为空,并且stack2为空,则队列为空。
{
printf("Empty!\n");
}
return Pop(s2);
}
------
或者:(推荐)
int enqueue(stack s1,elemtp x)
//s1是容量为n的栈,栈中元素类型是elemtp。
//入栈时只涉及到stack1
{
if(top1==n && !Sempty(s2)){ //s1满s2非空,这时s1不能再入栈。
printf(“栈满”);
return(0);
}
if(top1==n && Sempty(s2)) { //s1满s2空,先将s1退栈,元素再压栈到s2。
while(!Sempty(s1)) {
POP(s1,x);
PUSH(s2,x);
}
PUSH(s1,x);
return(1); //x入栈,实现了队列元素的入队。
}
void dequeue(stack s2,s1){
//s2是输出栈,本算法将s2栈顶元素退栈,实现队列元素的出队。
if(!Sempty(s2)) //栈s2不空,则直接出队。
{
POP(s2,x);
printf(“出队元素为”,x);
}
else //处理s2空栈。
if(Sempty(s1)) {
printf(“队列空”);
exit(0);
}//若输入栈也为空,则判定队空。
else{ //先将栈s1倒入s2中,再作出队操作。
while(!Sempty(s1)){
POP(s1,x);
PUSH(s2,x);
}
POP(s2,x); //s2退栈相当队列出队。
printf(“出队元素”,x);
}
}//结束算法dequue。
int queue_empty(){
//本算法判用栈s1和s2模拟的队列是否为空。
if(Sempty(s1)&&Sempty(s2))
return(1);//队列空。
else return(0); //队列不空。
}