3-9 堆栈模拟队列 (20分) HBU-DS

3-9 堆栈模拟队列 (20分) HBU-DS

设已知有两个堆栈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()

输入格式:

输入首先给出两个正整数N1N2,表示堆栈S1S2的最大容量。随后给出一系列的队列操作: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

~

这个题哈哈哈,好像是我写了好多道题来,一次提交就AC的题。

思路

队列是先进先出,堆栈是后进先出。连个堆栈来模拟队列。比如输入的是1 2 3,那么进第一个堆栈从top往下就是3 2 1 ,输出的话就是 3 2 1,如果把他再入栈另一个堆栈,两次顺序相反,顺序自然就正了。

不能输入一个数就先放到s1里,然后立马弹出到s2中,因为这样和直接放入s2没有差别。要想保证这个顺序不会出错,从s1往s2转移的时候,s2里面不能有东西,而且s1得一下子全部转移到s2里。

就是要push的时候,如果s1没有东西,那就push,如果栈满了,就看s2,如果s2空着,那就把s1全部弹到s2里,然后再把这个数push到s1里;如果s2里有东西,那就不能push了。(这个时候,s2的最上面的元素是要下一个输出的,相当于队列的头部,你要是把s1的元素弹过来,顺序就乱了)

要pop的时候,如果s2里面有东西,那就直接弹出,如果没有东西看s1,如果s1为空,那就真没东西了,要是s1还有东西,那就把s1全部弹出到s2里,再让s2pop一个。

注意:因为要把s1的元素一下子pop到s2,那么s1的空间一定比s2小!

代码

#include <iostream>
using namespace std;
typedef struct SNode *Stack;
struct SNode
{
    int *data;
    int top;
    int MaxSize;
};
Stack CreatStack(int n)
{
    Stack s = (Stack)malloc(sizeof(SNode));
    s->MaxSize = n;
    s->data = (int *)malloc(sizeof(int) * n);
    s->top = -1;
    return s;
}
int main()
{
    int N1, N2;
    cin >> N1 >> N2;
    if (N1 > N2)
    {
        int temp = N1;
        N1 = N2;
        N2 = temp;
    }
    Stack s1 = CreatStack(N1);
    Stack s2 = CreatStack(N2);

    char op;
    int n;
    while (cin >> op)
    {
        if (op == 'T')
            break;
        if (op == 'A')
        {
            cin >> n;
            if (s1->top == s1->MaxSize - 1) //a full
            {
                if (s2->top != -1) //b no empty
                    cout << "ERROR:Full" << endl;
                else
                {
                    while (s1->top != -1)
                        s2->data[++s2->top] = s1->data[s1->top--];
                    s1->data[++s1->top] = n;
                }
            }
            else // a 没满
                s1->data[++s1->top] = n;
        }
        else if (op == 'D')
        {
            if (s2->top == -1) //b empty
            {
                if (s1->top == -1)
                    cout << "ERROR:Empty" << endl;
                else
                {
                    while (s1->top != -1)
                        s2->data[++s2->top] = s1->data[s1->top--];
                    cout << s2->data[s2->top--] << endl;
                }
            }
            else //b 有东西
                cout << s2->data[s2->top--] << endl;
        }
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值