您的位置:首页 > 理论基础 > 数据结构算法

用两个队列模拟一个栈

2015-07-25 23:23 330 查看
    有一段时间没用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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 队列