剑指offer 学习笔记 用两个栈实现队列

面试题9:用两个栈实现队列。队列声明如下,实现它的appendTail和deleteHead函数,分别表示在队尾插入节点和在队列头删除节点。

template <typename T> class CQueue {
public:
    CQueue();
    ~CQueue();

    void appendTail(const T &node);
    T deleteHead();
private:
    stack<T> stack1;
    stack<T> stack2;
};

首先分析一下往该队列中插入和删除元素的过程,首先插入一个元素a,不妨把它插入stack1,再向stack1中压入两个元素b、c,此时stack2是空的。此时,我们想从队列中删除一个元素,由于a先进,因此a先出,但a在栈底,我们可以把stack1中所有元素依次先出栈再压入stack2,完成后stack1为空,而stack2的栈顶就是a了。如我们还想出队列,继续弹出stack2的栈顶元素即可。因此,当我们想出队列且stack2不为空时,直接弹出stack2的栈顶元素即可;当stack2为空时,将stack1中所有元素依次弹出并压入stack2,之后再弹出即可。

考虑继续向队列插入元素,我们直接向stack1插入元素即可:
在这里插入图片描述

#include <iostream>
#include <stack>
using namespace std;

template <typename T> class CQueue {
public:
    void appendTail(const T& node);
    T deleteHead();
private:
    stack<T> stack1;
    stack<T> stack2;
};

template <typename T> T CQueue<T>::deleteHead() {
    if (stack2.size() == 0) {
        while (stack1.size() > 0) {
            stack2.push(stack1.top());
            stack1.pop();
        }
    }

    if (stack2.size() == 0) {
        throw exception("empty queue");
    }

    T res = stack2.top();    // 此处不能定义为引用以提高效率,因为栈顶元素在下句代码被弹出
    stack2.pop();

    return res;
}

template <typename T> void CQueue<T>::appendTail(const T &node) {
    stack1.push(node);
}

int main() {
    CQueue<int> q;
    q.appendTail(1);
    q.appendTail(2);
    q.appendTail(3);
    q.appendTail(4);
    q.appendTail(5);
    cout << q.deleteHead() << endl;
}

相关题目:
1.用两个队列实现一个栈。分析:我们先往栈中压入元素a,不妨将a放入queue1中,接下来往栈中压入元素b、c,我们将b、c都存入queue1中,这样a位于queue1的队列头,b、c紧随其后。当我们想弹出一个元素时,如上例,应该弹出c,我们就可以把queue1中元素依次出队列再入队列queue2,这样c是queue1中最后一个出队列的,将c删除即可,这样,queue2中从头到尾元素为a、b,弹出b时重复以上步骤即可。当我们想压入元素d时,直接放在有元素的队列的队尾即可,这样再出栈时,按以上步骤出栈的还是d,符合栈的后进先出特点。
在这里插入图片描述

#include <iostream>
#include <deque>
using namespace std;

template <typename T> class CStack {
public:
    void push(const T &);
    T pop();
private:
    deque<T> que[2];
};

template <typename T> void CStack<T>::push(const T& t) {
    int i = 0;

    if (que[i].size() == 0) {    // 向有元素的队列插入
        i = 1 - i;
    }

    que[i].push_back(t);
}

template <typename T> T CStack<T>::pop() {
    int i = 0;

    if (que[i].size() == 0) {
        i = 1 - i;
    }
    if (que[i].size() == 0) {
        throw exception("empty stack");
    }

    while (que[i].size() != 1) {
        que[1 - i].push_back(que[i].front());
        que[i].pop_front();
    }

    T res = que[i].front();
    que[i].pop_front();

    return res;
}

int main() {
    CStack<int> s;
    s.push(1);
    s.push(2);
    s.push(3);
    s.push(4);
    cout << s.pop() << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值