两个队列实现一个栈,首先我们必须清楚以下几点:
栈的特点是“后进先出”,而队列的特点是“先进先出”;
在插入元素时栈和队列都是在尾部进行的,但是在删除元素时,队列是从对头开始删除的,栈是从栈顶开始的。
解决这个问题提供两种方法:
1.队列q1,q2,用q1作为维护栈的主队列,q2作为辅助.
入栈,将元素直接插入到q1中;
出栈:(1)将q1中(除队尾元素外)的所有元素依次弹出并插入到q2中;
(2)将q1中剩下的那个元素直接弹出;
(3)将q2中的所有元素依次导入到q1中.
代码实现:
template<class T>
class DoubleQueue_Stack
{
public:
void Push(const T& d);
void Pop();
bool Empty();
size_t Size();
T& Top();
private:
queue<T> q1;
queue<T> q2;
};
template<class T>
void DoubleQueue_Stack<T>::Push(const T& d)
{
q1.push(d);
}
template<class T>
void DoubleQueue_Stack<T>::Pop()
{
//q1 0-1-2-3
assert(!q1.empty());
while(q1.size()>1)
{
q2.push(q1.front()); //q2 0-1-2
q1.pop();
}
q1.pop(); //pop掉3
//q2是0-1-2,进入下面循环后,q1为0-1-2,再进入上面的循环,q2 0-1,2直接pop,直到pop出0
while(!q2.empty())
{
q1.push(q2.front());
q2.pop();
}
}
template<class T>
bool DoubleQueue_Stack<T>::Empty()
{
return q1.empty();
}
template<class T>
size_t DoubleQueue_Stack<T>::Size()
{
return q1.size();
}
template<class T>
T& DoubleQueue_Stack<T>::Top()
{
return q1.back();
}
2.通过两个队列共同维护一个栈
入栈:每次将元素入进不为空的队列里,方便操作;
出栈:和上面不同的是这种方法只要哪个队列不为空就可执行pop操作(一次pop操作后,定有一个队列为空),不用每次都将元素倒入一个队列中才执行pop,只是在需要的时候才进行导入。
下面是代码实现:
template<class T>
class DoubleQueue_Stack
{
public:
void Push(const T& d);
void Pop();
bool Empty();
size_t Size();
T& Top();
private:
queue<T> q1;
queue<T> q2;
};
template<class T>
void DoubleQueue_Stack<T>::Push(const T& d)
{
if(!q1.empty())
{
q1.push(d);
}
else
{
q2.push(d);
}
}
template<class T>
void DoubleQueue_Stack<T>::Pop()
{
assert(!q1.empty()||!q2.empty());
if(!q1.empty())
{
while (q1.size()>1)
{
q2.push(q1.front());
q1.pop();
}
q1.pop();
}
else if(!q2.empty())
{
while (q2.size()>1)
{
q1.push(q2.front());
q2.pop();
}
q2.pop();
}
}
template<class T>
bool DoubleQueue_Stack<T>::Empty()
{
return q1.empty()&&q2.empty();
}
template<class T>
size_t DoubleQueue_Stack<T>::Size()
{
if (!q1.empty())
{
return q1.size();
}
return q2.size();
}
template<class T>
T& DoubleQueue_Stack<T>::Top()
{
assert(!q1.empty()|| !q2.empty());
if(!q1.empty())
{
return q1.back();
}
if(!q2.empty())
{
return q2.back();
}
}