剑指Offer学习总结-用两个栈实现队列
本系列为剑指Offer学习总结,主要是代码案例的分析和实现:
书籍链接:http://product.dangdang.com/24242724.html
原作者博客:http://zhedahht.blog.163.com/blog/static/254111742011101624433132/
原作者博客链接有完整的项目代码下载。
用两个栈实现队列
题目
题目:用两个桟实现一个队列。 队列的声明如下, 请实现它的两个数 appendTail 和 deleteHead,
分别完成在队列尾部插入结点和在队列头部删除结点的功能。
队列的定义如下
template <typename T> class CQueue
{
public:
CQueue(void);
~CQueue(void);
void appendTail(const T& node);
T deleteHead();
private:
stack<T> stackl;
stack<T> stack2;
}
一个队列中包含了两个栈,我们可以先来简单模拟一下看栈在这里该怎么用。
思路分析
我们通过一个具体的例子来分析往该队列插入和删除元素的过程。
先插入一个元素 a, 不妨先把它插入到 stack1, 此时 stackl 中的元素有{ a },stack2 为空
再压入两个元素 b 和 c, 还是插入到 stack1 中, 此时 stack1 中的元素有{ a,b,c }
其中 c 位于栈顶, 而 stack2 仍然是空的.
我们试着删除一个元素,按照队列的特点,先进的需要先出。
先进的是a,我们需要先出,但是a现在位于栈的底部,只能后出,
所以我们可以利用stack2,将stack1中的元素入栈stack2,
然后从stack2中出栈。
如果还想继续删除元素,我们先看Stack2中有无元素,如果有直接出栈,
如果没有,我们重新将stack1的元素入栈stack2。
完整的解法:
//入队列
template<typename T> void CQueue<T>::appendTail(const T& element)
{
stack1.push(element);
}
//出队列
template<typename T> T CQueue<T>::deleteHead()
{
//stack2为空
if(stack2.size()<= 0)
{
//将stack1的元素入栈stack2
while(stack1.size()>0)
{
T& data = stack1.top();
stack1.pop();
stack2.push(data);
}
}
//如果stack2还是空,则抛出异常队列为空
if(stack2.size() == 0)
throw new exception("queue is empty");
//stack2存在元素 弹出栈顶
T head = stack2.top();
stack2.pop();
return head;
}