文章目录
1)题目
用两个栈实现队列(相关题目:用两个队列实现栈)
要求:
- 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
- 用两个队列来实现一个栈,完成栈的Push和Pop操作。栈中的元素为int类型。
2)思路
首先需要明确栈和队列的特点,栈为“先进后出”结构,队列为”先进先出“结构。
(1)用两个栈来实现一个队列的思路
- 实现队列的push操作: 首先创建两个栈stack1与stack2,将元素压入stack1,此时stack2为空。
- 实现队列的pop操作: 由于队列为”先进先出“结构,所以先压入stack1的元素需要先出列,分两种情况,第一,在stack2为空的和stack1不为空的情况下,将stack1的元素出栈并一一压入stack2中,就把原来在stack1栈底的元素现在在stack2的栈顶,所以直接pop出stack2的栈顶元素即可完成队列的pop操作。第二种情况为stack2不为空,那直接pop出stack2的栈顶元素即可完成队列的pop操作。
存在问题:
上述思路,可行性毋庸置疑。但有一个细节是可以优化一下的。即:在出队时,将s1的元素逐个“倒入”s2时,原在s1栈底的元素,不用“倒入”s2(即只“倒”s1.Count()-1个),可直接弹出作为出队元素返回。这样可以减少一次压栈的操作。
三个方法变种:
- 入队时,先判断s1是否为空,如不为空,说明所有元素都在s1,此时将入队元素直接压入s1;如为空,要将s2的元素逐个“倒回”s1,再压入入队元素。
- 出队时,先判断s2是否为空,如不为空,直接弹出s2的顶元素并出队;如为空,将s1的元素逐个“倒入”s2,把最后一个元素弹出并出队。
- 入队时,将元素压入s1。出队时,判断s2是否为空,如不为空,则直接弹出顶元素;如为空,则将s1的元素逐个“倒入”s2,把最后一个元素弹出并出队。这个思路,避免了反复“倒”栈,仅在需要时才“倒”一次。
上述方法总体上时间复杂度和空间复杂度应该相差无几。
注意事项:
要考虑没有元素可供出队时的处理(2个栈都为空的时候,出队操作一定会引起异常)。在实际写代码时,忽略这些判断或异常处理,程序会出现问题
(2)用两个队列来实现一个栈的思路
- 实现栈的push操作: 新元素入栈时,若两个队列都为空,向任意一个队列队尾插入元素,否则向其中一个非空队列插入元素。
- 实现栈的pop操作: 由于队列为”先进后出“结构,所以先入队的元素需要先出栈,栈弹出元素时,将非空队列的元素依次删除,插入另一个空队列,只留下队尾元素(此即栈顶元素),弹出栈顶即从队列中删除此元素。
注意事项:
在此过程中,新push进来的元素总是插入到非空队列中,空队列则用来保存pop操作之后的那些元素,那么此时空队列不为空了,原来的非空队列变为空了,总是这样循环。
3)代码
参考文章1
参考文章2
代码分为两部分,用两个栈来实现一个队列,完成队列的Push和Pop操作。用两个队列来实现一个栈,完成栈的Push和Pop操作。栈中的元素为int类型。
(1)用两个栈来实现一个队列,完成队列的Push和Pop操作
//第三种方案
#pragma once
#include <iostream>
#include<vector>
#include <stack>
using namespace std;
class CQeue
{
private:
stack<int> stack1;
stack<int> stack2;
public:
void appendtail(int element)
{
stack1.push(element);
}
int deletehead()
{
if (stack2.size() <= 0)
{
while (stack1.size() > 0)
{
int data=stack1.top();
stack1.pop();
stack2.push(data);
}
}
if (stack2.size() == 0)
{
cout << "stack is empty" << endl;
}
int head=stack2.top();
stack2.pop();
return head;
}
};
主函数
//#include <iostream>
//#include "offer_9.h"
//using namespace std;
//
//
//int main()
//{
// CQeue temp;
// //temp.appendtail(1);
// //temp.appendtail(2);
// //temp.appendtail(3);
// int result = temp.deletehead();
// //cout << result << endl;
// //int result1 = temp.deletehead();
// //cout << result1 << endl;
// //int result2 = temp.deletehead();
// //cout << result2 << endl;
// return 0;
//}
(2)用两个队列来实现一个栈,完成栈的Push和Pop操作
要点:新元素入栈时,若两个队列都为空,向任意一个队列队尾插入元素,否则向其中一个非空队列插入元素。栈弹出元素时,将非空队列的元素依次删除,插入另一个空队列,只留下队尾元素(此即栈顶元素),弹出栈顶即从队列中删除此元素。
#pragma once
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
class CStack
{
private:
queue<int> queue1;
queue<int> queue2;
public:
void appendtail(int element)
{
if (queue1.empty())
{
queue2.push(element);
}
else if (queue2.empty())
{
queue1.push(element);
}
}
int deletehead()
{
int head;
if (queue2.empty())
{
while (queue1.size() != 1)
{
int data = queue1.front();
queue2.push(data);
queue1.pop();
}
head = queue1.back();
queue1.pop();
}
else if (queue1.empty())
{
while (queue2.size() != 1)
{
int data = queue2.front();
queue1.push(data);
queue2.pop();
}
head = queue2.back();
queue2.pop();
}
return head;
}
};