《算法導論》10.1-6 用兩個棧實現一個隊列,並分析相關隊列操做的運行時間。html
把棧頂元素當作隊尾元素,向隊尾插入的操做能夠直接用棧的push來完成,這道題的關鍵是如何實現從隊頭刪除的操做。算法
相應的,棧底元素就至關於隊頭元素,咱們知道,棧底元素是不能自由進出的,而棧頂元素能夠,若是咱們能夠把待刪除的棧底元素移到棧頂的位置,就能夠把它刪掉了。數組
如何把棧底元素移到棧頂位置呢?這裏就須要另外一個棧B的幫助了,當咱們把元素從棧A依次彈出,壓入棧B,咱們實際上是完成了一個把棧A逆序排列存入棧B的過程。this
當把B的棧頂彈出後,再反過來把棧B元素逆序排列存入棧A,獲得的新的棧A正好是咱們想要的原棧A移除棧底以後的結果。spa
#include "stack.h" template<typename Object> class QueueByStacks { public: QueueByStacks() { for(int i = 0; i != NUM; ++i) pStack[i] = new Stack<Object>; } QueueByStacks(const QueueByStacks& rhs) { for(int i = 0; i != NUM; ++i) pStack[i] = new Stack<Object>(*(rhs.pStack[i])); } QueueByStacks(QueueByStacks&& rhs) { for(int i = 0; i != NUM; ++i) { pStack[i] = rhs.pStack[i]; rhs.pStack[i] = nullptr; } } QueueByStacks& operator =(const QueueByStacks& rhs) { QueueByStacks copy(rhs); for(int i = 0; i != NUM; ++i) std::swap(this->pStack[i], copy.pStack[i]); return *this; } QueueByStacks& operator =(QueueByStacks&& rhs) { for(int i = 0; i != NUM; ++i) std::swap(this->pStack[i], rhs.pStack[i]); return *this; } ~QueueByStacks() { for(int i = 0; i != NUM; ++i) { if(pStack[i]) delete pStack[i]; } } void enqueue(const Object& object) //運行時間爲O(1) { pStack[0]->push(object); } void enqueue(Object&& object) { pStack[0]->push(std::move(object)); } Object dequeue() //運行時間爲O(n),n爲隊列長度 { while(!pStack[0]->empty()) { Object& object = pStack[0]->top(); pStack[0]->pop(); pStack[1]->push(object); } Object& ret = pStack[1]->top(); pStack[1]->pop(); while(!pStack[1]->empty()) { Object& object = pStack[1]->top(); pStack[1]->pop(); pStack[0]->push(object); } return ret; } bool empty() const {return pStack[0]->empty();} bool full() const {return pStack[0]->full();} private: static constexpr int NUM = 2; Stack<Object>* pStack[NUM]; }; void testQueueByStacks() { using namespace std; struct Student { char name[10]; int age; }; constexpr int NUM = 5; Student students[NUM] = {Student{"Tom", 12},Student{"Micheal", 13}, Student{"Anna", 14},Student{"Lily", 10}, Student{"James", 19}}; QueueByStacks<Student> q; for(int i = 0; !q.full() && i != NUM; ++i) q.enqueue(students[i]); for(int i = 0; i != NUM; ++i) { q.dequeue(); q.enqueue(std::move(students[i])); } decltype(q) q_copy (q); decltype(q_copy) q_move(std::move(q_copy)); while(!q_move.empty()) { auto stu = q_move.dequeue(); cout << "name: " << stu.name << " age: " << stu.age << endl; } } /*output: name: Micheal age: 13 name: Anna age: 14 name: Lily age: 10 name: James age: 19 */