用两个队列模拟一个栈

1 篇文章 0 订阅
1 篇文章 0 订阅

    有一段时间没用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



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值