如何用兩個棧實現一個隊列

  • 棧有一種妙用,當把棧A中的元素逐個Pop出棧,Push入另外一個空的棧B中後,棧B中元素將是原棧A中元素的倒序排列。運用這個性質,即可以實現將棧A的棧底元素彈出的操做。試想,若是一個棧不只支持棧頂元素的入棧出棧,還支持棧底元素的出棧,那麼它不就已經具有了隊列的功能了嘛。html

    來自《算法導論》習題10.1-6,爲了讓代碼更清晰地表達思路,就讓棧的元素類型是int吧。
    stack.h所包含的class Stack的實現見博文 http://www.javashuo.com/article/p-ruqmmpiu-hk.html算法

#include "stack.h"
class QueueByStacks
{
public:
    QueueByStacks(int len);
    ~QueueByStacks() = default;

    void Enqueue(int val);
    void Dequeue();
    int Front();
    int Back() const;
    bool IsEmpty() const;
    bool IsFull() const;
private:
    static void InvertStack(Stack& from, Stack& to);
private:
    Stack m_stack;
    Stack m_stack_invert;
};


QueueByStacks::QueueByStacks(int len)
    :m_stack(len),
      m_stack_invert(len)
{}

//時間爲O(1)
void QueueByStacks::Enqueue(int val)
{
    if(!m_stack.IsFull())
        m_stack.Push(val);
    else
        cout << "Overflow" << endl;
}

//時間爲O(n)
void QueueByStacks::Dequeue()
{
    InvertStack(m_stack, m_stack_invert);
    m_stack_invert.Pop();
    InvertStack(m_stack_invert, m_stack);
}

//時間爲O(n)
int QueueByStacks::Front()
{
    InvertStack(m_stack, m_stack_invert);
    int ret = m_stack_invert.Top();
    InvertStack(m_stack_invert, m_stack);
    return ret;
}

//時間爲O(1)
int QueueByStacks::Back() const
{
    return m_stack.Top();
}

bool QueueByStacks::IsEmpty() const
{
    return m_stack.IsEmpty();
}

bool QueueByStacks::IsFull() const
{
    return m_stack.IsFull();
}

void QueueByStacks::InvertStack(Stack &from, Stack &to)
{
    assert(to.IsEmpty());
    while(!from.IsEmpty())
    {
        to.Push(from.Top());
        from.Pop();
    }
}
相關文章
相關標籤/搜索