两个队列实现栈
原创
©著作权归作者所有:来自51CTO博客作者legend05070911的原创作品,请联系作者获取转载授权,否则将追究法律责任
两个队列实现栈:
(一)前提:
//前提已知
typedef struct queue
{
int queuesize;
int head, tail;
int *q;
}Queue;
void InitQueue(Queue *q);
void EnQueue(Queue *q, int key);
int DeQueue(Queue *q);
int SizeOfQueue(Queue *q);
int IsQueueEmpty(Queue *q);
int IsQueueFull(Queue *q);
(二)方法一:
(1)图解:
(2)解析:
q1是专职进出栈的,q2只是个中转站,(q2不存储数据)。
1)入栈时:直接入队列q1即可
2)出栈时:把q1的除最后一个元素外全部转移到队q2中,然后把刚才剩下q1中的那个元素出队列。之后把q2中的全部元素转移回q1中。
(3)代码实现:
void Push(Queue *q1, Queue *q2, int k)
{
EnQueue(q1, k);
}
int Pop(Queue *q1, Queue *q2)
{
int tmp;
if(IsQueueEmpty(q1) == 1)//队列1为空。
{
printf("Stack Empty!\n");
}
else
{
while(SizeOfQueue(q1) != 1)
{
EnQueue(q2, DeQueue(q1));
}
tmp = DeQueue(q1);//出栈
while(IsQueueEmpty(q2) == 0)
{
EnQueue(q1, DeQueue(q2));
}
return tmp;
}
}
(4)问题:
出栈时最后仍然需要将q2中的数据压入到q1中。
(三)改进:
(1)解析:
定义两个指针:pushtmp:所指专门进栈的队列; tmp:指向临时作为中转站的另一个栈。
1)入栈时:直接入pushtmp所指队列即可
2)出栈时:把pushtmp的除最后一个元素外全部转移到队列tmp中,然后把刚才剩下q1中的那个元素出队列。然后更新pushtmp,tmp。
比较:方法二,转移到另外一个队列后不用返回了,这样减少了转移的次数。
(2)代码实现:
void Push(Queue *q1, Queue *q2, int k)
{
Queue *pushtmp, *tmp;
if(IsQueueEmpty(q1) == 0)//q1非空
{
pushtmp = q1;
tmp = q2;
}
else
{
pushtmp = q2;
tmp = q1;
}
EnQueue(pushtmp, k);
}
int Pop(Queue *q1, Queue *q2)
{
int tmpvalue;
Queue *pushtmp, *tmp;
if(!IsQueueEmpty(q1))//q1非空。
{
pushtmp = q1;
tmp = q2;
}
else
{
pushtmp = q2;
tmp = q1;
}
if(IsQueueEmpty(pushtmp))
{
printf("Stack Empty!\n");
}
else
{
while(SizeOfQueue(pushtmp) != 1)
{
EnQueue(tmp, DeQueue(pushtmp));
}
tmpvalue = DeQueue(pushtmp);
return tmpvalue;
}
}
--------
或者:
思路:
1)若用两个queue实现(可以定义成queue的数组queue q[2]),可以增加一个currentIndex来指向当前选中的queue。
2)入栈操作可以直接把元素加到queue里,即 queue[currentIndex].push(element),时间复杂度为O(1),
3)处理方法是将size()-1个元素从q[currentIndex]转移到空闲队列q[(currentIndex + 1)%2]中,q[currentIndex]最后一个剩下的元素恰对应栈顶元素,之后更新一下currentIndex即可,时间复杂度为O(N)。
4)实现:
#include <iostream>
#include <queue>
#include <cassert>
using namespace std;
template <class T>
class YL_Stack
{
public:
YL_Stack():currentIndex(0)
{
}
void push(const T &element); //入栈
void pop(); //出栈
T top(); //栈顶元素
size_t size() const; //栈的大小
bool empty() const; //判断栈是否为空
private:
int currentIndex;
queue<T> q[2];
};
template <class T>
void YL_Stack<T>::push(const T &element)
{
q[currentIndex].push(element);
}
template <class T>
size_t YL_Stack<T>::size() const
{
return q[0].size()+q[1].size();
}
template <class T>
bool YL_Stack<T>::empty() const
{
return (size()==0);
}
template <class T>
void YL_Stack<T>::pop()
{
assert(!empty());
int index=(currentIndex+1)%2;
while(q[currentIndex].size()>1)
{
T temp=q[currentIndex].front();
q[currentIndex].pop();
q[index].push(temp);
}
q[currentIndex].pop();
currentIndex=index;
}
template <class T>
T YL_Stack<T>::top()
{
assert(!empty());
int index=(currentIndex+1)%2;
T temp;
while(q[currentIndex].size()>0)
{
temp=q[currentIndex].front();
q[currentIndex].pop();
q[index].push(temp);
}
currentIndex=index;
return temp;
}
void main()
{
YL_Stack<int> myStack;
myStack.push(1);
myStack.push(2);
myStack.push(3);
myStack.push(4);
myStack.push(5);
cout<<"1栈的大小为:"<<myStack.size()<<endl;
cout<<"1栈顶元素为:"<<myStack.top()<<endl;
myStack.pop();
myStack.pop();
myStack.pop();
cout<<"2栈的大小为:"<<myStack.size()<<endl;
cout<<"2栈顶元素为:"<<myStack.top()<<endl;
}