算法 (六)自定义栈获取栈元素最小值(getMin)、队列模拟栈、栈模拟队列

1、自定义栈获取栈元素最小值(getMin)

1.1 简单描述

自定义一个栈的元素,实现获得最小元素的方法:getMin

1.2 思路:
  1. 调用两个Java栈集合,一个数据栈dataStack,一个辅助栈helpStack
  2. 压栈操作:同时压入,data栈正常压入,help栈:
    a:如果没有元素,就压入新元素
    b:如果有元素,小于help栈顶元素,就压入新元素
    c:如果大于或者等于help栈顶元素,就重复压入栈顶元素
    始终保持help栈顶元素是data栈里面的最小元素
  3. 弹栈操作:一起弹
  4. 获取最小值:获取help栈的栈顶元素
1.3 具体实现代码:
package cn.nupt.sort;

import java.util.Stack;

public class Stack_getMin {

	/**
	 * @Description: 自定义栈,实现getMin,即找到栈中最小值的方法
	 *
	 * @author PizAn
	 * @date 2019年1月27日 上午11:45:48
	 * 
	 */
	public static class MyStack {

		// 注:如果你自定义的类的名字和你所引用的相同,那么会强制带上前缀
		// 比如这里的类名如果也是Stack,下面就不能再引用java.util.Stack;需要加上前缀

		// 1、建立两个栈(用Java自带的栈集合)一个是dataStack,一个是helpStack

		private Stack<Integer> dataStack;
		private Stack<Integer> helpStack;

		public MyStack() {
			this.dataStack = new Stack<Integer>();
			this.helpStack = new Stack<Integer>();

		}

		// 压栈
		public void push(Integer obj) {
			// data栈直接压
			dataStack.push(obj);
			// help栈需要判断一下,如果栈里没有数,就把第一个数压入,如果data栈里面新来的数比help栈顶(即最小的数)小,就压入
			// 如果大于或者等于,就重复压入相同的数

			if (helpStack.isEmpty()) { // 如果,help栈为空,直接将新数放进去
				helpStack.push(obj);
			} else if (obj >= helpStack.peek()) { // help栈不为空,且新数大于等于help栈的栈顶元素,重复压入栈顶元素
				helpStack.push(helpStack.peek());
			} else { // 新数小于栈顶元素,压入新数(始终保持help栈里面是data栈中最小的元素)
				helpStack.push(obj);
			}

		}

		// 弹栈
		public Integer pop() { // 弹栈的话,两个栈一起弹
			if (dataStack.isEmpty()) {
				throw new ArrayIndexOutOfBoundsException("The Stack is empty!");

			}

			Integer popNum = dataStack.pop();
			helpStack.pop();

			return popNum;

		}

		// 获得栈顶元素,返回data栈的栈顶元素
		public Integer peek() {
			if (dataStack.isEmpty()) {
				throw new ArrayIndexOutOfBoundsException("The Stack is empty!");

			}

			return dataStack.peek();

		}

		// 获得栈的最小元素,也就是获得help栈的栈顶元素(因为help栈的栈顶一直都是data栈的最小元素)
		public Integer getMin() {
			if (dataStack.isEmpty()) {
				throw new ArrayIndexOutOfBoundsException("The Stack is empty!");

			}

			return helpStack.peek();

		}

	}

}

2、队列模拟栈

2.1 简单描述

用队列模拟栈的实现,包括压栈push、弹栈pop、获得栈顶元素peek

2.2 思路:
  1. 调用两个Java队列集合,一个数据队列dataQueue,一个辅助队列helpQueue
    因为queue再Java里面只有接口,这里是用linkedList实现的
  2. 压栈操作:全部add到dataQueue里面
  3. 弹栈操作:因为栈是先进后出,队列是先进先出,所以先将dataQueue中的前N-1个元素全部add到helpQueue里面(留下一个屁股),然后把这个屁股”弹“出去,然后helpQueue和dataQueue互换姓名,重复上面的卖屁股操作
  4. 获取栈顶元素:和pop一样,不过拿到屁股之后还要再装回去
2.3 具体实现代码:
package cn.nupt.sort;

import java.util.LinkedList;
import java.util.Queue;

public class QueueToStack {
	/**
	 * @Description: 用队列模拟栈
	 *
	 * @author PizAn
	 * @date 2019年1月27日 下午3:08:03
	 * 
	 */
	public static class MyStack {
		// 1、建立两个Java自带队列,一个放数据,一个是辅助队列
		private Queue<Integer> dataQueue;
		private Queue<Integer> helpQueue;

		public MyStack() { // 构造函数,因为queue只有接口,这里底层是用 LinkedList实现的
			this.dataQueue = new LinkedList<Integer>();
			this.helpQueue = new LinkedList<Integer>();

		}

		// 压栈操作:全部压入dataQueue
		public void push(Integer obj) {
			dataQueue.add(obj);
		}

		// 弹栈操作
		public Integer pop() {

			if (dataQueue.isEmpty()) {
				throw new ArrayIndexOutOfBoundsException("The Stack is empty!");
			}
			while (dataQueue.size() > 1) {
				helpQueue.add(dataQueue.poll());

			}
			Integer res = dataQueue.poll();
			//交换两个队列的姓名
			swap();

			return res;

		}

		// 拿到栈顶元素
		public Integer peek() {
			if (dataQueue.isEmpty()) {
				throw new ArrayIndexOutOfBoundsException("The Stack is empty!");
			}
			while (dataQueue.size() > 1) {
				helpQueue.add(dataQueue.poll());

			}

			Integer res = dataQueue.poll();
			helpQueue.add(res); // 因为这里是拿到栈顶元素就行了,所以将这个元素还和其他元素一样放到help栈里
			swap();

			return res;

		}

		private void swap() {

			Queue<Integer> temp = dataQueue;
			dataQueue = helpQueue;
			helpQueue = temp;

		}

	}

}

3、栈模拟队列

3.1 简单描述

用栈实现队列,包括进队列push、出队列poll、获得队列第一个元素peek

3.2 思路:(其实想一下,只要用两个栈,就能把先进后出变成先进先出了,"倒"一下就行了)
  1. 调用两个Java栈集合,一个专管进队列pushStack,一个专管出队列 pollStack

  2. 进队列操作:全部压到pushStack里面

  3. 出队列操作:将pushStack里面的元素全部“倒”到 pollStack里面,然后从pollStack里面拿元素,这个里面有两点要注意:
    a:只有在pollStack为空的时候才能倒入元素
    b:pushStack倒元素到pollStack里面一定要一次性倒完,不要有剩余

  4. 获取队列首元素:直接调用pollStack的peek方法

3.3 具体实现代码:
package cn.nupt.sort;

import java.util.Stack;

/**
 * @Description: 用栈实现队列
 *
 * @author PizAn
 * @date 2019年1月27日 下午4:11:02
 * 
 */
public class StackToQueue {

	// 建立两个栈,其中一个只管push(进队列),另一个只管poll(出队列),将push里面的元素全部“倒”到poll里面,不就
	// 可以实现头朝下脚朝上,先进后出变成先进先出了么
	// 不过这里“倒”有个技巧,你只能在pop为空的时候倒,并且push要全部倒完才行

	private Stack<Integer> pushStack;
	private Stack<Integer> pollStack;

	public StackToQueue() {
		this.pushStack = new Stack<Integer>();
		this.pollStack = new Stack<Integer>();
	}

	// 进队列操作
	public void push(Integer obj) {
		pushStack.push(obj);

	}

	// 出队列操作
	public Integer poll() {
		if (pushStack.isEmpty() && pollStack.isEmpty()) {
			throw new ArrayIndexOutOfBoundsException("The queue is empty!");
		} else if (pollStack.isEmpty()) { // 条件1:poll栈是空的
			while (!pushStack.isEmpty()) { // 条件2:push栈不是空的
				pollStack.push(pushStack.pop());
			}
		}
		Integer res = pollStack.pop();

		return res;

	}

	public Integer peek() {
		if (pushStack.isEmpty() && pollStack.isEmpty()) {
			throw new ArrayIndexOutOfBoundsException("The queue is empty!");
		} else if (pollStack.isEmpty()) { // 条件1:poll栈是空的
			while (!pushStack.isEmpty()) { // 条件2:push栈不是空的
				pollStack.push(pushStack.pop());
			}
		}

		return pollStack.peek();

	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值