1、两个栈实现一个队列
有三种思路:
- 思路一:将stack1作为存储空间,将stack2作为临时缓冲区,入队时,直接压入stack1,出队时,将stack1中的元素依次出栈压入stack2中,再将stack2的栈顶元素弹出,最后将stack2中的元素再倒回给stack1
- 思路二:入队时,判断stack1是否为空,如果stack1为空,则将stack2中的所有元素都倒入stack1中,再将元素直接压入stack1,否则,直接压入stack1中 ;出队时,判断stack2是否为空,如果stack2为空,则将stack1中的元素倒入stack2中,在将stack2的栈顶元素弹出,否则,直接弹出stack2的栈顶元素
- 思路三:入队时,直接压入stack1中;出队时,判断stack2是否为空,如果stack2为空,则将stack1中的元素倒入stack2中,否则直接弹出stack2中的元素
可以看看下面的图,假设现在入队的元素是1,2,3,4,那么入队之后处在队头的元素为1,队尾为4,那么我们想要通过s1和s2实现这样的队列。
我们就把1,2,3,4压入s1中,当pop操作的时候,我们就把s1的元素都压入到s2中,然后对s2进行pop操作就相当于对队列的pop了。
思路一与思路二相比,如果是连续出栈操作或连续进栈操作,思路二比思路一好很多。思路三最好代码如下。
class Solution
{
public:
void push(int node) {
stack1.push(node);//先把元素压栈stack1
}
int pop() {
//当stack2中为空时,把栈stack1中的元素依次取出,再压入栈stack2
if(stack2.size()<=0){
while(stack1.size()>0){
int data=stack1.top();//取出栈顶元素
stack1.pop();//弹出栈顶元素
stack2.push(data);//压入栈2
}
}
int node= stack2.top();//stack2栈不为空,说明队列不为空,栈顶元素就是队列的队头
stack2.pop();
return node;
}
private:
stack<int> stack1;
stack<int> stack2;
};
2、两个队列实现一个栈
将queue1用作进栈出栈,queue2作为一个中转站
入栈时,直接压入queue1中
出栈时,先将queue1中的元素除最后一个元素外依次出队列,并压入队列queue2中,将留在queue1中的最后一个元素出队列即为出栈元素,最后还要把queue2中的元素再次压入queue1中
扫描二维码关注公众号,回复:
2731878 查看本文章
如下图:把a.,b,c压入队列(先入先出)queue1中,再删除a,b并且压入队列queue2中,此时就可以pop c出栈(后入先出),再pop b 出栈。
接下来我们考虑从栈内压入一个元素d.此时queue1已经有了一个元素,我们就把d插入到queue1的尾部。如果我们再从栈内弹出一个元素,此时被弹出的应该是最后被压入的d.由于d位于queue1的尾部,我们只能先从头部删除queue1的元素并插入到queue2,直到queue1中遇到d再直接把它删除。
注意:在上述思路中,两个队列存在全空队列和一个空队列的情况。所以,在程序中进入子函数第一步,要判断两个队列是否同时不为空(异常),增加程序的鲁棒性。另外,空栈删除元素要报异常,即两个队列均为空;
实现代码如下:
//进栈操作
void stackpush(queue<int> &q1,queue<int> &q2,int m)
{
q1.push(m);
}
//出栈操作
void stackpop(queue<int> &q1,queue<int> &q2,int &m)
{
int p = q1.size();
for (int i=0;i<p-1;i++)
{
q2.push(q1.front());
q1.pop();
}
m = q1.front();
q1.pop();
int l = q2.size();
for (int j = 0;j<l;j++)
{
q1.push(q2.front());
q2.pop();
}
}