比如我们使用的Word、Excel、Photoshop等软件系统中的撤销操作,也是栈的具体应用,最后做的操作,一定是最先撤销的。
参考:https://mp.weixin.qq.com/s/LhdUCq4o4YFP3ZpkXc2Dyg
数据和链表实现栈
public interface Stack<T> {
//返回栈的大小
public int size();
//判断栈是否为空
public boolean isEmpty();
//判断栈是否满了
public boolean isFull();
//入栈
public boolean push(T t);
//出栈
public Object pop() throws StackEmptyException;
//返回栈顶元素
public Object peek() throws StackEmptyException ;
}
public class StackEmptyException extends RuntimeException {
//新增栈为空的异常类
public StackEmptyException(String eMeaasge ){
super(eMeaasge);
}
}
/**
* 基于数组实现的顺序栈
*
* @param <E>
*/
public class ArrayStack<E> implements Stack<E> {
private Object[] data = null; //栈元素数组
private int Maxsize = 0; //栈容量
private int top = -1; //栈顶元素下标
private final int DEFAULT_SIZE = 20;
public ArrayStack() {
init(DEFAULT_SIZE); //默认初始化大小为20的栈
}
public ArrayStack(int initialSize) {
init(initialSize);
}
//初始化栈
private void init(int initialSize) {
if (initialSize >= 0) {
this.Maxsize = initialSize;
data = new Object[Maxsize];
top = -1;
System.out.println("大小为" + Maxsize + "的栈初始化成功!");
} else {
System.out.println("栈大小不能小于0:" + initialSize);
}
}
@Override
public int size() {
return top+1;
}
//判断栈是否为空
@Override
public boolean isEmpty() {
return top == -1;
}
//判断栈是否满
@Override
public boolean isFull() {
return top >= Maxsize - 1;
}
//压栈操作
@Override
public boolean push(E e) {
if (isFull()) {
System.out.println("栈已满,操作失败");
return false;
} else {
top++;
data[top] = e;
System.out.println("元素‘" + e + "’入栈");
return true;
}
}
//出栈操作
@Override
@SuppressWarnings("unchecked")
public E pop() {
if (isEmpty()) {
System.out.println("空栈!操作失败");
return null;
} else {
E e = (E) data[top];
data[top] = null; //元素出栈后数组该位置置空
top--;
return e;
}
}
//取栈顶元素但不出栈
@Override
public E peek() {
if (isEmpty()) {
System.out.println("栈为空!操作失败");
return null;
} else {
return (E) data[top];
}
}
public static void main(String[] args) {
ArrayStack<Integer> stackArray = new ArrayStack<Integer>();
System.out.println(stackArray.size());
stackArray.push(1);
stackArray.push(2);
stackArray.push(5);
stackArray.push(6);
System.out.println(stackArray.size());
while(!stackArray.isEmpty()){
System.out.println(stackArray.pop());
}
}
}
链栈
public class Node {
private int value;
private Node next;
public Node() {
}
public Node(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
}
public class LinkedStack implements Stack<Node> {
private final int DEFAULT_SIZE = 20;
public int size;
public Node top;
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public boolean isFull() {
return size == DEFAULT_SIZE;
}
@Override
public boolean push(Node node) {
if (isFull()) {
System.out.println("栈满了..");
return false;
} else {
Node curr = top;
top = node;
top.setNext(curr);
size++;
return true;
}
}
@Override
public Node pop() throws StackEmptyException {
if (isEmpty()) {
System.out.println("栈为空!操作失败");
return null;
} else {
Node next = top.getNext();
Node ret = top;
top = next;
size--;
return ret;
}
}
// 取栈顶元素但不出栈
@Override
public Node peek() throws StackEmptyException {
if (isEmpty()) {
System.out.println("栈为空!操作失败");
return null;
} else {
return top;
}
}
public static void main(String[] args) {
LinkedStack linkedStack = new LinkedStack();
linkedStack.push(new Node(1));
linkedStack.push(new Node(2));
linkedStack.push(new Node(3));
linkedStack.push(new Node(4));
linkedStack.push(new Node(5));
while (!linkedStack.isEmpty()) {
System.out.println(linkedStack.pop());
}
}
}
package com.example.demo.day03;
import java.util.Scanner;
public class TrainArrange {
// 缓冲铁轨中编号最小的车厢
private static int minH = Integer.MAX_VALUE;
//minH号车厢对应的缓冲铁轨
private static int minS = -1;
public static boolean railRoad(int[] p, int k) {
LinkedStack[] h = new LinkedStack[k];
for (int i = 0; i < h.length; i++) {
h[i] = new LinkedStack();
}
int nowOut = 1; //下一次要输出的车厢号
//int minH = Integer.MAX_VALUE;
//int minS = -1; //
for (int i = 0; i < p.length; i++) {
if (p[i] == nowOut) {
System.out.println("移动车厢:" + p[i] + "从入轨到出轨。");
nowOut++;
//System.out.println("minH:"+minH);
//System.out.println("minS:"+minS);
//从缓冲铁轨中输出
while (minH == nowOut) {
output(h); //出轨
nowOut++;
}
} else {
//将p[i]送入某个缓冲铁轨
if (!input(p[i], h)) {
return false;
}
}
}
return true;
}
/**
* 在一个缓冲铁轨中放入车厢C
*
* @param c 放入车厢编号
* @param h 缓冲轨道的集合
* @return 如果没有可用的缓冲铁轨,则返回false,否则返回true
*/
public static boolean input(int c, LinkedStack[] h) {
int bestTrack = -1; //目前最优的铁轨
int bestTop = Integer.MAX_VALUE; //最优铁轨上的头辆车厢
//找到 C 存放的最佳位置
for (int i = 0; i < h.length; i++) {
if (!h[i].isEmpty()) {
int x = h[i].top.getValue();
if (c < x && x < bestTop) {
bestTop = x;
bestTrack = i;
}
} else {
if (bestTrack == -1) {
bestTrack = i;
break;
}
}
}
if (bestTrack == -1)
return false;
h[bestTrack].push(new Node(c));
System.out.println("移动车厢:" + c + "从入轨到缓冲轨" + bestTrack);
if (c < minH) {
minH = c;
minS = bestTrack;
}
return true;
}
/**
* 从缓冲轨移除车厢出轨
*
* @param h 缓冲轨道的集合
*/
public static void output(LinkedStack[] h) {
h[minS].pop(); //从堆栈minS中删除编号最小的车厢minH
System.out.println("移动车厢:" + minH + "从缓冲轨" + minS + "到出轨。");
//通过检查所有的栈顶,搜索新的minH和minS
minH = Integer.MAX_VALUE;
minS = -1;
for (int i = 0; i < h.length; i++) {
if (!h[i].isEmpty() && h[i].top.getValue() < minH) {
minH = h[i].top.getValue();
minS = i;
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] p = new int[]{3, 6, 9, 2, 4, 7, 1, 8, 5};
int k = 3;
boolean result = railRoad(p, k);
do {
if (!result) {
System.out.println("需要更多的缓冲轨道,请输入需要添加的数量");
k = k + sc.nextInt();
result = railRoad(p, k);
}
} while (!result);
}
}