面试题7:用两个栈实现队列
题目:用两个栈实现一个队列。
队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除
结点的功能。
1 template <typename T> 2 class CQueue 3 { 4 public: 5 CQueue(); 6 ~CQueue(); 7 void appendTail(const T& node); 8 T deleteHead(); 9 private: 10 stack<T>stack1; 11 stack<T>stack2; 12 };
分析:栈的特点是后入先出,队列的特点是先入先出。首先按照入队列的顺序将数据压入栈stack1中,那么当需要删除队首元素时意味着要删除栈底元素,此时可利用另一个栈进行数据转移,按照stack1出栈的顺序将数据压入stack2中,此时stack2的栈顶元素
即为队首元素。此时可将stack2中的元素再转移回stack1中,当需要删除队首元素时重复这个过程。事实上,最后一步转移可以省略,因为当有元素需要插入队列时,直接将改元素压入stack1中,当需要删除队首元素时,如果stack2非空,直接从stack2中弹出栈顶元素如果stack2为空,则将stack1中的数据转移至stack2中。代码如下:
1 template <typename T> 2 void CQueue::appendTail(const T& node) 3 { 4 stack1.push(node); 5 } 6 template <typename T> 7 T deleteHead() 8 { 9 if (stack2.empty() && stack1.empty()) 10 throw new exception("queue is empty") ; 11 if (stack2.empty()) 12 { 13 while (!stack1.empty()) 14 { 15 stack2.push(stack1.top()); 16 stack1.pop(); 17 } 18 } 19 T node = stack2.top(); 20 stack2.pop(); 21 return node; 22 }
相关题目:用两个队列实现一个栈
分析:队列的特点是先入先出,因此若要弹出栈顶元素即要删除队列的尾元素,此时,可利用另一个队列进行数据转移。和栈不同的是,这种转移操作不影响数据的顺序。
- push:找到一个非空队列,并将数据插入到队列尾部
- pop: 找到一个非空队列,并将该队列除了队尾元素全部转移到另一个队列中,删除队尾元素。