用两个队列模拟一个栈
2015-07-25 23:23
330 查看
有一段时间没用C++和数据结构的东西了,感觉有点荒废,今天呆着没事把队列实现栈这个问题动手用C++写了一下。
这里实现了两种方法,一种入栈的复杂度是O(1),出栈O(n),一种入栈O(n),出栈O(1),更好的方法我还没有想到,如果你有更好的方法还望告诉我一下。
代码如下:
#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
这里实现了两种方法,一种入栈的复杂度是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
相关文章推荐
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构揭秘一
- 算法系列15天速成 第九天 队列
- C++基于栈实现铁轨问题
- 数据结构之Treap详解
- C语言单链队列的表示与实现实例详解
- C语言栈的表示与实现实例详解
- C语言实现颠倒栈的方法
- 算法系列15天速成 第十天 栈
- mysql 队列 实现并发读
- C#队列Queue用法实例分析
- C#多线程处理多个队列数据的方法
- C语言循环队列的表示与实现实例详解
- C++循环队列实现模型
- C#内置队列类Queue用法实例
- 一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out
- JavaScript数据结构和算法之图和图算法
- Array栈方法和队列方法的特点说明
- 【数据结构之旅】稀疏矩阵的快速转置