设已知有两个堆栈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
该题的思路主要是创建s1和s2两个栈模拟队列的操作;刚开始让s1成为最大容量小的那个栈;然后在s1中进行入队操作,以及特殊情况的判断和处理;在s2中进行出队操作,和特殊情况的判断和处理.
代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
//声明栈
typedef struct {
int* data;
int top;
}stack;
//初始化栈
void Initstack(stack* s, int n) {
s->data = (int*)malloc(sizeof(int) * n);
s->top = -1;
}
//判断栈是否为空
bool Isempty(stack s) {
if (s.top == -1)
return true;
return false;
}
//入栈
void push(stack* s, int n) {
s->data[++s->top] = n;
}
//出栈
int pop(stack* s) {
int x;
x = s->data[s->top--];
return x;
}
int main()
{
char c;
int e;
int n1, n2,num1,num2;
stack s1, s2;//定义两个栈
scanf("%d %d", &num1, &num2);
//经过判断,让s1为容量小的那个栈
if (num1 > num2)
{
n1 = num2;
n2 = num1;
}
else
{
n1 = num1;
n2 = num2;
}
Initstack(&s1, n1);
Initstack(&s2, n2);
scanf("%c", &c);
while (c != 'T')
{
scanf("%d", &e);
//进行入栈时的判断
//1.如果s1满了,s2中有足够的空间存放s1中的数据;通过循环将s1中的数据移到s2中。
//此时s2中的栈顶数据,即为先进来的数据,由此来模拟队列的“先进先出”。
if (c == 'A' && s1.top == n1 - 1 && s1.top - s2.top >= n1)
{
int count = 0;
while (count < n1)
{
push(&s2, pop(&s1));
count++;
}
push(&s1, e);
}
//2.如果s1满了,并且s2中也没有足够的空间存放s1的数据,所以无法进行入队操作,就输出ERROR:Full。
else if (c == 'A' && s1.top == n1 - 1)
{
printf("ERROR:Full\n");
}
//3.如果s1没满,正常入栈
else if (c == 'A')
{
push(&s1, e);
}
//进行出栈时的判断
//1.如果s1和s2同时为空,无法进行出队操作,就输出ERROR:Empty。
if (c == 'D' && Isempty(s2) && Isempty(s1))
{
printf("ERROR:Empty\n");
}
//2.如果s2是空的,s1不空,就将s1中的数据压入s2中,将s1中的栈顶数据和栈末数据反转,再进行出队。
else if (c == 'D' && Isempty(s2) && !Isempty(s1))
{
while (!Isempty(s1))
{
push(&s2, pop(&s1));
}
printf("%d\n", pop(&s2));
}
//3.如果s2不为空,就正常出队
else if (c == 'D' && !Isempty(s2))
{
printf("%d\n", pop(&s2));
}
scanf("%c", &c);
}
return 0;
}
如果有什么不足或者改进的地方还希望各位大佬能够指点一下.