一.题目
设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。
输入格式:
输入首先给出两个正整数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
二.分析
1.题意
- 用两个栈,一个来存放输入时的数据,一个用来将输入的数据先后倒一下。
- 堆栈先入后出,队列先入先出 。
- 小栈当作输入栈,大栈保存从小栈中移动过去的值,作为输出栈。(如果把较大的栈作为输入栈的话,较小的栈无法缓冲从较大的栈中转移过来的值)
2.输入输出的一些相关情况
A(输入)
- s1 没满,直接放入 s1 中
- s1 满了,s2 为空,先把 s1 中的值都暂存到 s2 中,再保存到 s1 中
- s1 满了, s2 非空,此时需要输出 ERROR:Full (这是因为如果 s1 满了,无论再怎么放入 s1 或者 s2 都会打乱输出的顺序 )
D(输出)
- s2 非空,直接输出 s2.top()
- s1 非空, s2 为空, 那么将 s1 中的值放入 s2 中,然后输出 s2.top()
- s1 和 s2 都为空,那么输出 ERROR:Empty
三.代码
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int num;
struct node *next;
}Node, *Stack;
Stack Create(){
Stack s;
s = (Stack) malloc (sizeof(Node));
s -> next = NULL;
return s;
}
void Push(Stack s, int item){ //元素item压入堆栈s
Stack p = (Stack) malloc (sizeof (Node));
p -> num = item;
p -> next = s -> next;
s -> next = p;
}
int Pop(Stack s){ //删除并返回s的栈顶元素
Stack q;
int n;
q = s -> next;
n = q -> num;
s -> next = q -> next;
free(q);
return n;
}
int main(){
Stack s1 = Create();
Stack s2 = Create();
int n1, n2;
scanf("%d%d", &n1, &n2);
int temp; //确保n1是小容量,n2是大容量
if(n1 > n2){
temp = n1;
n1 = n2;
n2 = temp;
}
int count1 = 0, count2 = 0; //count1:容量小的栈中的个数
while(1){
char ch;
int n;
scanf("%c", &ch);
if('A' == ch){
scanf("%d", &n);
getchar();
if(count1 < n1){
Push(s1, n);
count1++;
}else{
printf("ERROR:Full\n");
}
}else if('D' == ch){
if(count2 > 0){
printf("%d\n", Pop(s2));
count2--;
}else{
printf("ERROR:Empty\n");
}
}else if('T' == ch){
break;
}
if(count1 == n1 && count2 == 0){ //只要s1栈满,而s2空,就把s1全部转入s2
while(count1 != 0){
Push(s2, Pop(s1));
count1--;
count2++;
}
}
}
return 0;
}