剑指 Offer 09. 用两个栈实现队列

题目

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
样例:

在这里插入图片描述

  • 还是老样子, 大家先思考想一下栈和队列的性质。就大概知道知道怎么做了
  • 思路:
    • 栈是先进后出的数据结构, 队列是先进先出的性质
    • 很容易想到两个栈就可以实现 一个先进先出的性质
    • 这道题 他没有考虑栈的大小所以不需要考虑那么多 栈一 q1 栈二 q2
    • 首先 从q1依次pop出到q2中, 在从q2 pop出 不就是先进先出么!但是我们有几点要注意
      • 第一: 就是如果我们要得出一个数据我们必须从q2中拿
      • 第二:我们push进数据一定要q1push而不能q2大家可以想一下
      • 第三: 就是我们每次把q1中的数据pop到q2中(必须把q1pop空) 必须是q2已经空了, 我们想如果q2不空 我们就把q1的数据转移到q2中 那么q2原有的数据就不符合先进先出的原则了故这是一点
      • 第四: 这道题没有限制两个栈的大小, 如果限制了 什么时候队满呢
        • 如果限制大小的话 q2一定要比q1大 要不我们从q1转移到q2 q2就放不下来, 那么q1剩下来的数据就不符合原则了
        • 其次 我们很容易想到 q1和q2都满的时候队满 还有一种情况栈虽然没有装满但是对于队来说就是满的 当q1满了 q2中还有数据呢 这时队也是满的因为 q2中有数据就不能把q1的数据转移到q2中, 故队满。
  • 这道题的代码, 我会把限制栈大小的代码也会在后面给出
class CQueue {
public:
   stack<int> q1;                     //作为临时的  如果满了 
   stack<int> q2;                      //出栈用这个出  这个栈的大小必须比q1大
   CQueue() {

   }
   
   void appendTail(int value) {
       q1.push(value);
   }
   
   int deleteHead() {
       if (q2.empty()){
           while (!q1.empty()){
               int x = q1.top();
               q1.pop();
               q2.push(x);
           }
       }
       if (q2.empty()) return -1;
       int x = q2.top();
       q2.pop();
       return x;
   }
};

题目:

在这里插入图片描述

限制栈大小的代码


#include "iostream"
#include "string"
using namespace std;
const int N = 1000;
struct Stack{
    int MAXSIZE;
    int s[N];
    int tt;
}s1, s2;
int IsFull(Stack S){ 
    return S.tt == S.MAXSIZE;
}
int isEmpty(Stack S){
    return S.tt == 0;
}
void push (Stack &s, int x){
    if (IsFull(s)){
        cout << "ERROR:Full" << endl;
        return;
    }
	s.tt ++;
    s.s[s.tt] = x;
}
int pop (Stack &s){
    if (isEmpty(s)){
        cout << "ERROR:Empty" << endl;
        return 0;
    }
	
    int x = s.s[s.tt];
	s.tt--;
    return x;
}
int main(){
    int n1, n2;
    cin >> n1>> n2;
    s1.MAXSIZE = n1 > n2 ? n2 : n1;
    s2.MAXSIZE = n1 > n2 ? n1 : n2;
    s1.tt = 0;
    s2.tt = 0;
    string t;
    while (cin >> t, t != "T"){
        if (t == "A"){
            int x;
            cin >>x;
            if (IsFull(s1) && isEmpty(s2)){   //判断是否能转移到s2
                while (!isEmpty(s1)){
                    int i = pop(s1);
                    push(s2, i);
                }
            }
            if (!IsFull(s1)){              //s1不满一定不会满
                push(s1, x);
			}else
                cout << "ERROR:Full" << endl;
        }else{
           if(isEmpty(s2) && !isEmpty(s1)){     //当s2空的时候 s1不空的时候可以转移
                while (!isEmpty(s1) ){
                    int i = pop(s1);
                    push(s2, i);
                }
            }
            if (!isEmpty(s2)){             //s2不空证明队列不空
                cout << pop (s2) << endl;
            }
            else
                cout << "ERROR:Empty" << endl;
        }
    }
    return 0;
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值