栈&队列面试题之两个队列实现一个栈

来源:互联网 发布:淘宝店铺怎么虚拟发货 编辑:程序博客网 时间:2024/05/16 17:34

两个队列实现一个栈

  在之前我曾经实现了两个栈实现一个队列的面试题,其实思路也很简单就是充分利用栈的特性-后进先出,将输入的数据先输入栈1,将该栈1再输出到栈2,最后将栈2的数据输出,利用这个交换的特性实现两个栈实现一个队列.

  那仫如何利用两个队列实现一个栈呢?

思路分析篇:

  其实思路类似之前的面试题-两个栈实现一个队列,也是通过交换的特性:

 (1).先将要输入的数据类似 1->2->3->4->5输入到队列1中

 (2).在Pop时则需要一点技巧了,因为是模拟实现栈,所以出栈的顺序为5->4->3->2->1.如果队列1不为空则将队列1的前n-1个数据尾插到队列2中,队列1中只剩下最后一个元素n-在上面这种情况下我们将 1 2 3 4从队列1中删除尾插到队列2中,队列1中只剩下5

 (3).如果我们将队列1剩下的数据删除掉,则正好满足出栈顺序的第一个元素,此时队列1为空--如果此时再插入数据(6),我们只能将该数据尾插到队列2中(保证出栈顺序不被改变);如果我们没有将队列1中的最后一个元素n删除掉,则此时插入数据则将该数据插入到队列1中,同样是为了满足出栈顺序.

 (4).之前提到队列1为空,队列2为1->2->3->4->6,和刚才的想法类似,将队列2的前n-1个数据尾插到队列1中,队列2中只剩下最后一个元素n,将队列2中的最后一个数据Pop掉就是现在的栈顶元素啦!!!

     ...以后的步骤类似(4).

       下图是我画的一个简单的实现过程:

       

 代码实现篇:

      

//两个队列实现一个栈template<typename T>class StackBy2Queue{public:void Push(const T& x){if(_queue1.size() > 0)//如果队列1不为空则将数据插入到队列1中_queue1.push(x);else if(_queue2.size() > 0)//队列1为空队列2不为空插入到队列2中_queue2.push(x);else_queue1.push(x);}void Pop(){assert(!_queue1.empty() || !_queue2.empty());if(_queue2.empty()){//队列2为空时while(_queue1.size() > 1){//保留队列1原本的队尾元素_queue2.push(_queue1.front());_queue1.pop();}_queue1.pop();}else{//队列2不为空while(_queue2.size() > 1){//保留队列2的队尾元素_queue1.push(_queue2.front());_queue2.pop();}_queue2.pop();}}T& Top(){if(_queue1.size() > 0)return _queue1.back();elsereturn _queue2.back();}bool Empty(){//两个队列都为空时才为空return (_queue1.empty()) && (_queue2.empty());}size_t Size(){return _queue1.size()+_queue2.size();}private:queue<T> _queue1;queue<T> _queue2;};


 

      test.cpp

     

void testStackBy2Queue(){StackBy2Queue<int> sq;sq.Push(1);sq.Push(2);sq.Push(3);sq.Push(4);sq.Push(5);cout<<sq.Top()<<endl;  //5sq.Pop();cout<<sq.Top()<<endl;  //4sq.Push(6);cout<<sq.Top()<<endl;  //6cout<<sq.Size()<<endl;  //5sq.Pop();sq.Pop();sq.Pop();sq.Pop();sq.Pop();}


 

     

       这只是我个人的一点小小理解,如果有问题希望指出.

0 0