【数据结构】(面试题)使用两个栈实现一个队列(详细介绍)
使用两个栈实现一个队列
思路一:
我们设定s1是入栈的,s2是出栈的。
入队列,直接压到s1即可
出队列,先把s1中的元素倒入到s2中,弹出s2中的栈顶元素;再把s2的剩余元素全部倒回s1中。
缺点:
每次只要出栈一个元素就要将元素倒来倒去,麻烦!!!
思路2:
入队列时:
如果s1为空,把s2中所有的元素倒出压到s1中。否则直接压入s1
出队列时:
如果s2不为空,把s2中的栈顶元素直接弹出。否则,把s1的所有元素全部弹出压入s2中,再弹出s2的栈顶元素
思路1无条件地每次都要将元素倒来倒去,思路2出队时较思路1简单
思路3:
我们设定s1是入栈的,s2是出栈的
入队列:直接压入元素至s1即可
出队列:如果s2不为空,把s2中的栈顶元素直接弹出。否则,把s1的所有元素全部弹出压入s2中,再弹出s2的栈顶元素
相比于方法2,入队直接压入即可~
那么,我们可以看出,思路三最简单,我们下面看下代码。
代码实现:
1)我们直接调用库里的stack来实现。(一般调用库里的就行了)
#define_CRT_SECURE_NO_WARNINGS1#include<iostream>usingnamespacestd;//两个栈实现一个队列#include<stack>template<classT>classQueue{public:voidappendTail(constT&x){s1.push(x);}voiddeleteHead(){if(s2.empty()){while(!s1.empty()){s2.push(s1.top());s1.pop();}cout<<s2.top()<<"";s2.pop();}else{cout<<s2.top()<<"";s2.pop();}}private:stack<T>s1;stack<T>s2;};voidTest(){Queue<int>q;q.appendTail(1);q.appendTail(2);q.appendTail(3);q.appendTail(4);q.deleteHead();q.deleteHead();q.deleteHead();q.deleteHead();}intmain(){Test();system("pause");return0;}
2)自己实现栈实现。
#define_CRT_SECURE_NO_WARNINGS1#include<iostream>usingnamespacestd;#include<assert.h>//直接实现Stack,也可以用适配器实现栈,或者用库。//将Stack基本功能实现如下:template<classT>classStack{public:Stack():_array(NULL),_size(0),_capacity(0){}Stack<T>(constStack<T>&s):_array(newT[s._capacity]){swap(_array,s._array);swap(_size,s._size);swap(_capacity,s._capacity);}Stack<T>&operator=(constStack<T>&s){if(&s!=this){swap(_array,s._array);swap(_size,s._size);swap(_capacity,s._capacity);}return*this;}~Stack(){if(_array){delete[]_array;_array=NULL;}}void_CheckCapacity(){if(_size==0){_capacity=3;_array=newT[_capacity];}if(_size>=_capacity){_capacity*=2;T*tmp=newT[_capacity];for(intindex=0;index<_size;index++){tmp[index]=_array[index];}delete[]_array;_array=tmp;}}voidPush(constT&x){_CheckCapacity();_array[_size++]=x;}voidPop(){if(_size==0){return;}--_size;}size_tSize(){return_size;}boolEmpty(){returnSize()==0;}T&Top(){assert(_size>0);return_array[_size-1];}private:T*_array;size_t_size;size_t_capacity;};template<classT>classQueue{public:voidInQueue(constT&x){s1.Push(x);}voidOutQueue(){//栈s2为空,则将栈s1的元素全部倒入s2中,再弹出最上面的那个元素if(s2.Empty()){while(!s1.Empty()){s2.Push(s1.Top());s1.Pop();}s2.Pop();}//栈s2不为空,直接弹出元素else{s2.Pop();}}voidPrint()//打印队列元素,分四种情况。{if(s1.Empty()&&s2.Empty()){cout<<"TheQueueisEmpty!";}elseif(!s1.Empty()&&s2.Empty()){while(!s1.Empty()){s2.Push(s1.Top());s1.Pop();}while(!s2.Empty()){cout<<s2.Top()<<"";s2.Pop();}}elseif(s1.Empty()&&!s2.Empty()){while(!s2.Empty()){cout<<s2.Top()<<"";s2.Pop();}}else{while(!s2.Empty()){cout<<s2.Top()<<"";s2.Pop();}while(!s1.Empty()){s2.Push(s1.Top());s1.Pop();}while(!s2.Empty()){cout<<s2.Top()<<"";s2.Pop();}}cout<<endl;}private:Stack<T>s1;//入队Stack<T>s2;//出队};//测试两个栈实现一个队列voidTest1(){Queue<int>q1;q1.InQueue(1);q1.InQueue(2);q1.InQueue(3);q1.InQueue(4);/*q1.Print();*/q1.OutQueue();/*q1.Print();*/q1.InQueue(5);q1.InQueue(6);q1.InQueue(7);q1.Print();}intmain(){Test1();system("pause");return0;}
(1个细节):
注意再将元素倒入另一个栈时,代码并不是先pop,再push。因为这样push后元素就找不到了。因此要先访问到栈顶元素top,再push,而后pop。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。