两个栈实现一个队列。两个队列实现一个栈

两个栈实现一个队列

方法一:我们先来说最笨的一种方法:倒栈

大多数人的思路是:始终维护s1作为存储空间,以s2作为临时缓冲区。

入队时,将元素压入s1。

出队时,将s1的元素逐个“倒入”(弹出并压入)s2,将s2的顶元素弹出作为出队元素,之后再将s2剩下的元素逐个“倒回”s1。

见下面示意图:                             

 

不得不说,这个方法虽然可行,但真的是有点笨。。。

方法二.加了一个判断s2是否为空的过程,减少倒栈次数

入队列:直接压入元素至s1即可

出队列:如果s2不为空,把s2中的栈顶元素直接弹出。否则,把s1的所有元素全部弹出压入s2中,再弹出s2的栈顶元素

乍看没什么问题了,但其实还是有个细节要考虑的。其实无论什么方法和情况,都要考虑没有元素可供出队时的处理(2个栈都为空的时候,出队操作一定会引起异常(细节问题)

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

template<class T>
void CQueue<T>::appendTail(const T& node)//在队列尾部添加数据
{
    stack1.push(node);
}
template<class T>
T CQueue<T>::deleteHead()
{
    T tmp = 0;
    if (stack2.empty()) //若栈2为空
    {
        while (!stack1.empty())
        {
            tmp = stack1.top();
            stack2.push(tmp);
            stack1.pop();
        }
    }
    tmp = stack2.top();
    stack2.pop();
    return tmp;
}

两个队列实现一个栈

入队时,谁空入谁,如果都空,则随意,假设初始入的是q1

出队时,把q1中的前size()-1个元素弹出,进入q2,弹出q1中的最后一个元素,再把q2中前size()-1个元素弹入q1,将q2中的最后一个元素出队,循环往复

如果此过程中有新元素入队,则哪个队列是空的入哪个队列。

template <typename T>
class CStack
{
public:
    CStack(void)
    {}
    ~CStack(void)
    {}
    void appendTail(const T& node);
    T deleteHead();
private:
    queue<T> q1;
    queue<T> q2;
};

template<class T>
void CStack<T>::appendTail(const T& node)//在栈尾部添加数据
{
    if (!q1.empty())//不为空的执行push操作
    {
        q1.push(node);
    }
    else
    {
        q2.push(node);
    }
}
template<class T>
T CStack<T>::deleteHead()
{
    int ret = 0;
    if (q1.empty())
    {
        int i = q2.size();
        while (i > 1 )//将q2队列中的数据pop到只剩一个
        {
            q1.push(q2.front());
            q2.pop();
            --i;
        }
        ret = q2.front();
        q2.pop();
    }
    else
    {
        int i = q1.size();
        while (i > 1)
        {
            q2.push(q1.front());
            q1.pop();
            --i;
        }
        ret = q1.front();
        q1.pop();
    }
    return ret;

  

代码参考:http://blog.csdn.net/zw_1510/article/details/51927554  

 

原文地址:https://www.cnblogs.com/curo0119/p/8611068.html