面试题:用两个栈实现一个队列

来源:互联网 发布:php soapclient 超时 编辑:程序博客网 时间:2024/04/29 20:07

用两个栈实现一个队列,我们首先需要了解栈和队列的特点。

栈:后进先出,即它的插入与删除操作均是在栈顶执行的;

队列:先进先出,即它的插入是在队尾进行,而删除是在队头进行的。

思路如下:

用两个栈,一个栈用来进队,一个栈用来出队,当数据进入队列的时候,我们将其压入一个栈,当数据出队的时候,我们将保存在栈内的数据pop出来,将其按照出栈的顺序压入另外一个栈,然后pop栈顶的数据就实现了出队的操作。当我们进行入队操作的时候,直接将数据压入第一个栈,为了便于理解,示意图如下:


红色的是出队列时,我们需要pop的数据。在整个过程中,我们发现其实是可以进行优化的,当stack2为空时,出队时,我们可以减少一次压栈的过程,将stack1栈底的数据保留下来,直接pop。示意图如下:


整体思路总结如下:

1.stack1用来push数据,包括stack1为空,不为空的情况;

2.stack2用来pop数据,

     当stack2为空时,将stack1除了栈底元素pop出来,按照出栈的顺序压入stack2中,直接pop stack1的元素就实现了出队操作;

     当stack2不为空时,直接pop stack2。

需要特别注意的是,两个栈都为空的时候是不能进行出队操作的,写程序时需要特别注意这一点。

程序实现如下:

#include<iostream>#include<stack>#include<assert.h>using namespace std;template<typename T>class CQueue{           template <typename T>           friend ostream & operator<<(ostream& _cout, const CQueue <T> & queue);public:          CQueue()          {}          ~CQueue()          {}          CQueue( const CQueue & cqueue)          {                   stack1 = cqueue.stack1;                   stack2 = cqueue.stack2;          }           void Push(const T& d)          {                   stack1.push( d);          }           void Pop()          {                    assert(stack1.size() != 0 || stack2.size() != 0);                    if (stack2.size() != 0)                   {                             stack2.pop();                   }                    else                   {                              while ((stack1.size()!=1))                             {                                      stack2.push(stack1.top());                                      stack1.pop();                             }                             stack1.pop();                   }          }           T& Front()          {                    assert(stack1.size() != 0|| stack2.size() != 0);                    if (stack2.size() != 0 )                   {                              return stack2.top();                   }                    else                   {                              while (stack1.size() != 0)                             {                                      stack2.push(stack1.top());                                      stack1.pop();                             }                              return stack2.top();                   }          }           T& Back()          {                    assert(stack1.size() != NULL || stack2.size() != NULL);                    if (stack1.size() != 0)                   {                              return stack1.top();                   }                    else                   {                              while (stack2.size() != 0)                             {                                      stack1.push(stack2.top());                                      stack2.pop();                             }                              return  stack1.top();                   }          }           bool Empty()          {                    if (stack1.size()==0 && stack2.size() == 0)                   {                              return true ;                   }                    else                              return false ;          }           size_t Size()          {                    return stack1.size() + stack2.size();          }          private:           stack<T > stack1;           stack<T > stack2;};template<typename T>ostream& operator<< (ostream & _cout, const CQueue <T>& queue){//根据入队顺序输出           CQueue<T > cqueue(queue);           while (cqueue.stack2.size() > 0)          {                    _cout << cqueue.stack2.top() << " ";                   cqueue.stack2.pop();          }           while (cqueue.stack1.size()>0)          {                   cqueue.stack2.push(cqueue.stack1.top());                   cqueue.stack1.pop();          }           while (cqueue.stack2.size() > 0)          {                    _cout << cqueue.stack2.top() << " ";                   cqueue.stack2.pop();          }           _cout << " " ;           return _cout ;}void funtest(){           CQueue<int > cqueue;          cqueue.Push(1);          cqueue.Push(2);          cqueue.Push(3);          cqueue.Push(4);          cout << cqueue <<endl;          cout << cqueue.Front() << endl;          cqueue.Pop();          cout << cqueue << endl;          cout << cqueue.Back() << endl;          cqueue.Pop();          cout << cqueue << endl;          cout<<cqueue.Size()<<endl;          cout<<cqueue.Empty()<<endl;          getchar();}int main(){          funtest();           return 0;}
写Front()与Back()的时候,需要特别注意,不可以用pop优化的思路来写,那样的话当Front()在pop()前面的时候,队首元素没有入栈到stack2中,此时stack2不为空,pop的并不是队首元素,程序有bug。

0 0
原创粉丝点击