1、问题
栈和队列在实现上非常类似,
是否可以用栈实现队列?
问题分析
用栈实现队列等价于用“后进先出”的
特性实现 "先进先出" 的特性!
解决方案设计
实现思路
准备两个栈用于实现队列: stack_in 和 stack_out
当有新元素入队时:将其压入stack_in
当需要出队时:
stack_out.size() == 0 ;
将stack_in中的元素逐—弹出并压入stack_out
将stack_out的栈顶元素弹出
stack_out.size() > 0 ;
将 stack_out的栈顶元素弹出2、编程实验
用栈实现队列 StackToQueue.h
main.cpp
#include <iostream> #include"LinkQueue.h" #include"LinkStack.h" using namespace std; using namespace DTLib; template < typename T > class StackToQueue : public Queue<T> { protected: mutable LinkStack<T> m_stack_in; mutable LinkStack<T> m_stack_out; void move() const //O(n) { if(m_stack_out.size() == 0) { while(m_stack_in.size() > 0) { m_stack_out.push(m_stack_in.top()); m_stack_in.pop(); } } } public: void add(const T &e) //O(1) { m_stack_in.push(e); } void remove() //O(n) { move(); if(m_stack_out.size() > 0) { m_stack_out.pop(); } else { THROW_EXCEPTION(InvalidOperationException,"No element in current queue ..."); } } T front() const //O(n) { move(); if(m_stack_out.size() > 0) { return m_stack_out.top(); } else { THROW_EXCEPTION(InvalidOperationException,"No element in current queue ..."); } } void clear() //O(n) { m_stack_out.clear(); } int length() const //O(1) { return m_stack_in.size() + m_stack_out.size(); } }; int main() { StackToQueue<int> sq; for(int i=0;i<10;i++) { sq.add(i); } while(sq.length() > 0) { cout<<sq.front()<<" "; sq.remove(); } return 0; }
对比时间复杂度,可以看出虽然栈可以实现队列但并不是好的实验方案
3、问题
反之, 是否可以用队列实现栈?问题分析
本质为,用队列“先进先出”的特性实
现栈“后进先出”的特性!
解决方案设计
实现思路
-准备两个队列用于实现栈: queue_1[in]和queue_2[out]
当有新元素入栈时:将其加入队列[in]
当需要出栈时:
将队列[in]中的n-1个元素出队列,并进入队列[out]中
将队列[in]中的录后—个元素出队列(出栈)
交换两个队列的角色: queue_1[ in]和 queue_2[ out]4、编程实验
用队列实现栈 QueueToStack.h
#include <iostream> #include"LinkQueue.h" #include"LinkStack.h" using namespace std; using namespace DTLib; template < typename T > class QueueToStack : public Stack<T> { protected: LinkQueue<T> m_queue_1; LinkQueue<T> m_queue_2; LinkQueue<T>* m_pIn; LinkQueue<T>* m_pOut; void move() const //O(n) { int n = m_pIn->length() - 1; for(int i =0;i<n;i++) { m_pOut->add(m_pIn->front()); m_pIn->remove(); } } void swap() //O(1) { LinkQueue<T>* temp = NULL; temp = m_pIn; m_pIn = m_pOut; m_pOut = temp; } public: QueueToStack() { m_pIn = &m_queue_1; m_pOut = &m_queue_2; } void push(const T &e) //O(1) { m_pIn->add(e); } void pop() //O(n) { if(m_pIn->length() > 0) { move(); m_pIn->remove(); swap(); } else { THROW_EXCEPTION(InvalidOperationException,"No element in current stack ..."); } } T top() const //O(n) { if(m_pIn->length() > 0) { move(); return m_pIn->front(); } else { THROW_EXCEPTION(InvalidOperationException,"No element in current stack ..."); } } void clear() //O(n) { m_queue_1.clear(); m_queue_2.clear(); } int size() const { return m_queue_1.length() + m_queue_2.length(); } }; int main() { QueueToStack<int> qs; for(int i=0;i<10;i++) { qs.push(i); } while(qs.size() > 0) { cout<<qs.top()<<" "; qs.pop(); } return 0; }
5、小结
栈和队列在实现上非常类似,可以相互转化实现
两个栈“后进先出”叠加得到“先进先出”的特性
两个队列“先进先出”相互配合得到“后进先出”的特性
栈和队列相互转化的学习有助于强化本质的理解