有两个栈组成的队列

【题目】

编写一个类, 用两个栈实现队列, 支持队列的基本操作(add, poll, peek).

【难度】

二星

【分析】

  1. 栈是先进后出, 就像超市摆放的纯牛奶, 最先摆放的在最底下, 买家肯定是最后取走。
  2. 队列先进先出, 就像去食堂排队, 最先排队的最先买饭, 最先走人。
  3. 然而我们可以用两个栈模仿队列——stackPush, stackPop
  4. stackPush只管压入数据
  5. stackPop负责弹出数据

如图1-3, 我们往stackPush里面压入数字1~5, 弹出数据的时候, 只需要把stackPush里面的数据倒入stackPop里面, 然后弹出stackPop的栈顶元素1, 就实现了队列先进先出的特性。

说起来容易, 但是要注意以下两点:

1.  往stackPop里面倒入数据时必须一次性倒入

2. stackPop里面有数据时不能再往里倒入数据


1.  往stackPop里面倒入数据时必须一次性倒入

如果stackPush如图1-3, 如果我们先往stackPop里面倒入4和5, 此时弹出的数据就是4, 不符合队列的特性——先进先出

2. stackPop里面有数据时不能再往里倒入数据

如果stackPush里的1~5全部倒入了stackPop里面, 这时又往stackPush里面压入了6~10; 此时stackPop里面有数据1~5, 如果再把stackPush里面的6~10倒入stackPop的话, stackPop里面的数据从上到下就是6~10 1~5, 此时如果弹出的数据就是6, 不符合队列的特性。

【代码实现】

package 栈和队列;
import java.util.Stack;

public class TwoStackQueue {
	private Stack<Integer> stackPush;
	private Stack<Integer> stackPop;
	public TwoStackQueue() {
		this.stackPush = new Stack<Integer>();
		this.stackPop = new Stack<Integer>();
	}
	public void add(int newNum) {
		this.stackPush.push(newNum);
	}
	public int poll() {
		if(this.stackPop.isEmpty()&&this.stackPush.isEmpty()) {
			throw new RuntimeException("Your queue is empty.");
		}else if(this.stackPop.isEmpty()) {
			while(!this.stackPush.isEmpty()) {
				this.stackPop.push(this.stackPush.pop());
			}
		}
		return this.stackPop.pop();
	}
	public int peek() {
		if(this.stackPop.isEmpty()&&this.stackPush.isEmpty()) {
			throw new RuntimeException("Your queue is empty.");
		}else if(this.stackPop.isEmpty()) {
			while(!this.stackPush.isEmpty()) {
				this.stackPop.push(this.stackPush.pop());
			}
		}
		return this.stackPop.peek();
	}

}
【代码分析】

poll函数:

类实例调用pop函数, 如果stackPush和stackPop都为空的话, 说明我们的队列没有数据, 抛出异常;

如果stackPop为空, stackPush不为空的话, 把stackPush的数据一次性倒入stackPop, 然后弹出stackPop的栈顶元素;

之后再调用poll, 只要stackPop不为空, 就依次弹出栈顶元素, 直到stackPop为空, 跳转到步骤1继续执行


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值