PTA 堆栈模拟队列
题目描述:
设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。
所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数:
- int IsFull(Stack S):判断堆栈S是否已满,返回1或0;
- int IsEmpty (Stack S ):判断堆栈S是否为空,返回1或0;
- void Push(Stack S, ElementType item ):将元素item压入堆栈S;
- ElementType Pop(Stack S ):删除并返回S的栈顶元素.
实现队列的操作,即入队void AddQ(ElementType item)和出队ElementType DeleteQ()。
输入格式:
输入首先给出两个正整数N1和N2,表示堆栈S1和S2的最大容量。随后给出一系列的队列操作:A item表示将item入列(这里假设item为整型数字);D表示出队操作;T表示输入结束。
输出格式:
对输入中的每个D操作,输出相应出队的数字,或者错误信息ERROR:Empty。如果入队操作无法执行,也需要输出ERROR:Full。每个输出占1行。
样例:
输入样例:
3 2
A 1 A 2 A 3 A 4 A 5 D A 6 D A 7 D A 8 D D D D T
输出样例:
ERROR:Full
1
ERROR:Full
2
3
4
7
8
ERROR:Empty
思路:
本题要求使用两个栈实现队列的出队、入队,要想使用栈实现队列,首先要认识栈以及队列
- 队列(queue)是一种特殊的线性表,特殊之处在于它只允许在队列的前端(front)进行删除操作,而在队列的后端(rear)进行插入操作。
- 栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在栈顶进行插入和删除操作;
使用两个栈来实现队列的功能,既是使用栈的出栈入栈的特性实现队列的出栈入栈的特性;下面给出解题思路:
- 最先两个栈空(即队空),我们可以规定栈S1为入队使用的栈,规定栈S2为出队使用的栈;
- 当有入队请求时,我们按照入队顺序将元素进行压栈S1;
- 当有出队请求时,我们首先检查栈S2中是否还有元素:
①若S2为空栈,则将S1的元素依次出栈并入栈S2,当S1栈中所有元素均进入S1栈后,将S2的栈顶元素作为队头元素输出;
②若S2为非空栈,则直接将S2的栈顶元素作为队头元素输出;
需要格外注意
- 当有入队请求时,并且S1已满,则此时需要判断S2是否有元素,若S2为空,这可以将S1所有元素均出栈并压栈到S2中;若S2也有元素,则当前请求不能满足;
- 当有出队请求时,并且S2已空,则此时需要判断S1中是否有元素,若S1为非空,这可以将S1所有元素均出栈并压栈到S2中;若S1为空,则当前请求不能满足;
- 当S1的元素向S2转移时,一定要满足两点:①转移前S2为空栈,②转移后S1为空栈。
上述内容就可以通过两个栈实现队列。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<stack>
#include<queue>
using namespace std;
stack<int>s1;
stack<int>s2;
int main(){
int n1,n2,n;
scanf("%d%d",&n1,&n2);
if( n1 > n2 ){
int temp = n1;
n1 = n2;
n2 = n1;
}
char op[2];
scanf("%s",op);
int flag = 0;
while( op[0] != 'T' ){
if( op[0] == 'A' ){
int x;
scanf("%d ",&x);
if( s1.size() < n1 ) s1.push(x);
else if( s1.size() == n1 && !flag ){
while( s1.size() ){
s2.push( s1.top() );
s1.pop();
}
flag = 1;
if( s1.size() < n1 ) s1.push(x);
}
else printf("ERROR:Full\n");
}
else if( op[0] == 'D' ){
if( s1.size() == 0 && s2.size() == 0 ) printf("ERROR:Empty\n");
else if( s2.size() ){
printf("%d\n",s2.top());
s2.pop();
if( s2.size() == 0 ) flag = 0;
}
else{
while( s1.size() ){
s2.push( s1.top() );
s1.pop();
}
flag = 1;
printf("%d\n",s2.top());
s2.pop();
if( s2.size() == 0 ) flag = 0;
}
if( flag == 0 ){
while( s1.size() ){
s2.push( s1.top() );
s1.pop();
}
flag = 1;
}
}
scanf("%s",op);
}
return 0;
}