棧有一種妙用,當把棧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(); } }