如何用栈来实现队列
使用堆栈来实现队列是一个面试经常遇到的问题
使用两个堆栈来实现队列可以通过以下步骤来完成:
定义两个堆栈stack1和stack2,其中stack1用于入队操作,stack2用于出队操作。
1.当需要入队一个元素时,将元素压入stack1中。
2.当需要出队一个元素时,如果stack2不为空,则直接弹出stack2的栈顶元素;否则,将stack1中的所有元素依次弹出并压入stack2中,然后再弹出stack2的栈顶元素。
3.当需要判断队列是否为空时,只需要判断stack1是否为空即可。
直接上代码,用栈来实现队列
/**
* 用两个栈来模拟队列,根据栈先进后出的特点
*/
public class TwoStacksQueue {
public Stack<Integer> stackPush; // 用于压数据
public Stack<Integer> stackPop; //用于往外弹出数据
public TwoStacksQueue() {
stackPush = new Stack<Integer>();
stackPop = new Stack<Integer>();
}
// push栈向pop栈倒入数据
private void pushToPop() {
if (stackPop.empty()) {
while (!stackPush.empty()) {
stackPop.push(stackPush.pop());
}
}
}
public void add(int pushInt) {
stackPush.push(pushInt);
//这里可以每次都将新进来的数据都倒进pop栈中
pushToPop();
}
public int poll() {
//超出条件的判断,两个栈都没有数据时无法弹出数据
if (stackPop.empty() && stackPush.empty()) {
throw new RuntimeException("Queue is empty!");
}
//如果有数据,将数据倒进pop栈中.不要觉得这个多余,不会影响效率
pushToPop();
return stackPop.pop();
}
/**
只读不弹出的操作
*/
public int peek() {
if (stackPop.empty() && stackPush.empty()) {
throw new RuntimeException("Queue is empty!");
}
//每次都做数据从push-pop,保证代码健壮
pushToPop();
return stackPop.peek();
}
}
用队列来实现栈的功能
可以使用两个队列来实现栈。具体实现步骤如下:
1. 定义两个队列 queue 和 help,分别用于存储入栈和出栈的元素。
2.当需要添加数据时,直接加到queue.
3.需要弹出时,我们把queue的元素保留一个剩下的都放进help中,然后把剩下的这个弹出.弹出后,再把queue和help 指针交换.
4.peek方法,类似上面第三步的操作,有一点区别,在弹出时,把弹出的值加到help中,然后交换指针,把弹出的值返回.
下面看代码实现
public class TwoQueueStack<T> {
public Queue<T> queue;
public Queue<T> help;
public TwoQueueStack() {
queue = new LinkedList<>();
help = new LinkedList<>();
}
public void push(T value) {
queue.offer(value);
}
//弹出时,queue 剩余一个元素用于弹出,其他元素放进help 中
public T poll() {
while (queue.size() > 1) {
help.offer(queue.poll());
}
T ans = queue.poll();
Queue<T> tmp = queue;
queue = help;
help = tmp;
return ans;
}
//peek 方法和弹出有一点区别,剩余的一个元素弹出后,还要加到help 中
public T peek() {
while (queue.size() > 1) {
help.offer(queue.poll());
}
T ans = queue.poll();
//区别加到help中
help.offer(ans);
Queue<T> tmp = queue;
queue = help;
help = tmp;
return ans;
}
public boolean isEmpty() {
return queue.isEmpty();
}