分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
有一段时间没用C++和数据结构的东西了,感觉有点荒废,今天呆着没事把队列实现栈这个问题动手用C++写了一下。
这里实现了两种方法,一种入栈的复杂度是O(1),出栈O(n),一种入栈O(n),出栈O(1),更好的方法我还没有想到,如果你有更好的方法还望告诉我一下。
第一种方法
入栈的时候直接插入一个队(记为A)的队尾,出栈的时候由于要把A队队尾的元素取出,所以就把A中的元素除最后一个外依次放到另一个队列B中,最后一个直接丢弃。完成后把A和B互换,这样下次入栈再插入到A队尾即可。
第二种方法
假设B队中元素的顺序就是元素在栈中的顺序,越新加入的越靠近队首。再次入栈一个元素,插入到一个空的队列A中,然后再把B中的元素依次插入A中,这样由于B中的顺序是由旧及新,而A队队首是最新的,所以A队也是由旧及新。完成后把A和B互换,这样方便下次操作。
代码如下:
- #include <iostream>
- #include <utility>
- #include <stack>
- #include <queue>
- using namespace std;
- /*
- *虚基类,定义了四个方法,pop(),push(),top()和emtpy()
- *在基类中实现了empty()方法
- *除两个队列外,还有两个指向队列的指针,用以指向用来入栈的队列和用来出栈的队列
- */
- class QueueToStack{
- protected:
- queue<int> q1;
- queue<int> q2;
- queue<int> *Push=&q1;
- queue<int> *Pop=&q2;
- public:
- virtual void pop()=0;
- virtual void push(int n)=0;
- virtual int top()=0;
- bool empty(){return q1.empty() && q2.empty();}
- };
- /*
- *一种用两个队列实现栈的方法,入栈时间复杂度为O(1),出栈时间复杂度为O(n)
- *保证每次入栈元素加入Push队列队尾
- *Push指针指向的队列用来入栈,Pop指针指向的队列作为辅助,每次出栈将Push队列赋值到Pop上并丢弃Push队尾元素作为出栈
- *出栈完毕后将Push和Pop交换
- */
- class FastPush: public QueueToStack {
- public:
- void pop();
- void push(int n);
- int top();
- };
- void FastPush::push(int n){
- Push->push(n);
- }
- int FastPush::top(){
- return Push->back();
- }
- void FastPush::pop(){
- while(Push->size()>1){
- Pop->push(Push->front());
- Push->pop();
- }
- Push->pop();
- swap(Push,Pop);
- }
- /*
- *另一种实现方法,入栈操作是O(n),出栈操作是O(1)
- *保证每次入栈之后,Pop队列的顺序就是在栈中的顺序
- *Push队列作为辅助,每次入栈完毕后保证为空,入栈时,将元素加入Push队列,再将Pop队列复制到Push队列
- *最后将Push和Pop队列互换
- *由于每次入栈完成后Pop队列中元素的顺序都是栈顺序的,所以入栈的时候只需要吧Pop队列赋值到Push后边
- */
- class FastPop: public QueueToStack{
- public:
- void pop();
- void push(int n);
- int top();
- };
- void FastPop::pop(){
- Pop->pop();
- }
- int FastPop::top(){
- return Pop->front();
- }
- void FastPop::push(int n){
- Push->push(n);
- while(!Pop->empty()){
- Push->push(Pop->front());
- Pop->pop();
- }
- swap(Push,Pop);
- }
- int main()
- {
- stack<int> s;
- QueueToStack *qs1 = new FastPush;
- QueueToStack *qs2 = new FastPop;
- for(int i=0;i<10;i++){
- s.push(i);
- qs1->push(i);
- qs2->push(i);
- }
- for(int i=0;i<10;i++){
- cout<<s.top()<<"\t"<<qs1->top()<<"\t"<<qs2->top()<<endl;
- s.pop();
- qs1->pop();
- qs2->pop();
- }
- return 0;
- }
运行结果:
- G:\>QueueToStack.exe
- 9 9 9
- 8 8 8
- 7 7 7
- 6 6 6
- 5 5 5
- 4 4 4
- 3 3 3
- 2 2 2
- 1 1 1
- 0 0 0
分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
- #include <cstdlib>
- #include <iostream>
- #include <assert.h>
- #include <deque>
- using namespace std;
- /*两个队列模拟一个堆栈*/
- /*队列A、B
- 入栈:将元素依次压入到非空的队列,第一个元素压倒对列A
- 出栈:把队列A的前n-1个元素倒到队列B,把第n个元素去掉。此时数据在B中,下次操作,则对B操作。
- 栈顶:把队列A的前n-1个元素倒到队列B,把第n个元素作为栈顶*/
- template <typename T>
- class MyStack
- {
- public:
- //入栈,第一个元素进到队列deque1,以后每个元素进到非空的队列
- void push(T element)
- {
- if (deque1.empty() && deque2.empty())
- {
- deque1.push_back(element);
- }
- else if (!deque1.empty() && deque2.empty())
- {
- deque1.push_back(element);
- }
- else if (deque1.empty() && !deque2.empty())
- {
- deque2.push_back(element);
- }
- }
- //出栈,将非空队列的前n-1个元素转移到另一个空的队列,删除非空队列的第n个元素
- void pop()
- {
- if (!deque1.empty())
- {
- int size = deque1.size();
- for (int i=0; i<size-1; i++)
- {
- deque2.push_back(deque1.front());
- deque1.pop_front();
- }
- deque1.pop_front();
- }
- else
- {
- int size = deque2.size();
- for (int i=0; i<size-1; i++)
- {
- deque1.push_back(deque2.front());
- deque2.pop_front();
- }
- deque2.pop_front();
- }
- }
- //栈顶元素,将非空队列的前n-1个元素转移到另一个空的队列,将非空队列的第n个元素返回
- T top()
- {
- if (!deque1.empty())
- {
- int size = deque1.size();
- for (int i=0; i<size-1; i++)
- {
- deque2.push_back(deque1.front());
- deque1.pop_front();
- }
- T temp = deque1.front();
- deque1.pop_front();
- deque2.push_back(temp);
- return temp;
- }
- else
- {
- int size = deque2.size();
- for (int i=0; i<size-1; i++)
- {
- deque1.push_back(deque2.front());
- deque2.pop_front();
- }
- T temp = deque2.front();
- deque2.pop_front();
- deque1.push_back(temp);
- return temp;
- }
- }
- //栈是否为空
- bool empty()
- {
- return (deque1.empty()&&deque2.empty());
- }
- private:
- deque<T> deque1;
- deque<T> deque2;
- };
- int main(int argc, char *argv[])
- {
- MyStack<int> my;
- for (int i=0; i<10; i++)
- {
- my.push(i);
- }
- while (!my.empty())
- {
- cout<<my.top()<<" ";
- my.pop();
- }
- cout<<endl;
- }