目录
算法通关村 —— 队栈实现问题解析
栈的特点:后进先出 队的特点:先进先出
1 用栈实现队列
实现方式:将两个栈底部拼接到一起就能实现队列的效果
实现思路:将一个栈作为输入栈,用于压入push传入的数据;另一个栈作为输出栈,用于pop和peek操作。每次pop或peek时,若输出栈为空则将输入栈的全部数据依次弹出并压入输出栈,这样输出栈从栈顶往栈底的顺序就是队列从队首往队尾的顺序。
实现代码如下:
class MyQueue {
Deque<Integer> inStack; // 定义输入栈
Deque<Integer> outStack; // 定义输出栈
/**
*初始化输入、输出栈
*/
public MyQueue() {
inStack = new LinkedList<Integer>();
outStack = new LinkedList<Integer>();
}
/**
* 入队:压入输入栈
*/
public void push(int x) {
inStack.push(x);
}
/**
* 出队:将输入栈所有数据压入输出栈,再pop输出栈
*/
public int pop() {
if (outStack.isEmpty()) {
in2out();
}
return outStack.pop();
}
/**
* 获得队头元素:将输入栈所有数据压入输出栈,再pop输出栈
*/
public int peek() {
if (outStack.isEmpty()) {
in2out();
}
return outStack.peek();
}
/**
* 判断队列是否为空
*/
public boolean empty() {
return inStack.isEmpty() && outStack.isEmpty();
}
/**
* 将输入栈数据压入输出栈
*/
private void in2out() {
while (!inStack.isEmpty()) {
outStack.push(inStack.pop());
}
}
}
2 用队列实现栈
实现方式:使用两个队列实现,满足栈的特性,即最后入栈的元素最先出栈,
实现思路:在使用队列实现栈时,满足队列前端的元素是最后入栈的元素。则可使用两个队列实现栈的操作。其中queue1用于存储栈内的元素,queue2作为入栈操作的辅助队列。入栈时,先将元素入队queue2,此时queue2的前端元素为新入栈的元素,再将queue1和queue2互换,则queue1的元素即为栈内的元素,queue1的前端和后端分别对应栈顶和栈底。出栈只需移除queue1的前端元素并返回即可。获得栈顶元素操作只需获得queue1的前端元素并返回即可。由于queue1用于存储栈内元素,判断栈是否为空时,只需判断queue1是否为空。
实现代码如下:
class MyStack {
Queue<Integer> queue1; // 定义存储元素的队列
Queue<Integer> queue2; // 定义入栈操作的队列
/**
* 初始化
*/
public MyStack() {
queue1 = new LinkedList<Integer>();
queue2 = new LinkedList<Integer>();
}
/**
* 入栈:先将元素入队到queue2,再将queue1所有元素出队并入队到queue2
* 再将queue1和queue2互换
*/
public void push(int x) {
queue2.offer(x);
while (!queue1.isEmpty()) {
queue2.offer(queue1.poll());
}
Queue<Integer> temp = queue1;
queue1 = queue2;
queue2 = temp;
}
/**
* 出栈:将queue1前端元素出队并返回
*/
public int pop() {
return queue1.poll();
}
/**
* 显示栈顶元素:获得queue1的前端元素并返回
*/
public int top() {
return queue1.peek();
}
/**
* 判空:判断queue1是否为空
*/
public boolean empty() {
return queue1.isEmpty();
}
}