栈(英语:stack)又称为栈或堆叠,是计算机科学中一种特殊的串列形式的抽象数据类型,其特殊之处在于只能允许在链表或数组的一端(称为堆栈顶端指针,英语:top)进行加入数据(英语:push)和输出数据(英语:pop)的运算。另外栈也可以用一维数组或链表的形式来完成。堆栈的另外一个相对的操作方式称为队列。
由于堆栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。
其基本的结构,如下图:
参考了一篇BLOG,借用其中的图片,可以很清晰的看到其模型(侵立删):
初始化 init: -> Stack
出栈 push: N x Stack -> Stack
获取栈顶元素,不出栈 peek: Stack -> (N U ERROR)
出栈 pop: Stack -> Stack
是空栈 isempty: Stack -> Boolean
JAVA接口定义 public interface StackInterface<T> { /** * 出栈 * * @return */ T pop(); /** * 进栈 * * @param t */ void push(T t); /** * 获取栈顶元素,未出栈 * * @return */ T peek(); /** * 检查是否为空栈 * * @return */ boolean isEmpty(); /** 清空栈 */ void clear(); /** * 当前栈深度 * * @return */ int length(); } 栈的实现代码 package com.tao.struct.stack; public class BaseStack<T> implements StackInterface<T> { // 默认栈的空间长度 private final int DEFAULT_STACK_SIZE = 8; // 当前栈的指向 private int top = -1; T[] objects = null; public BaseStack() { //JAVA 不支持泛型数组,只能这么做了 :):grimacing: objects = (T[]) new Object[DEFAULT_STACK_SIZE]; } @Override public T pop() { if (isEmpty()) { return null; } T t = objects[top--]; return t; } @Override public void push(T t) { if (top >= DEFAULT_STACK_SIZE - 1) { throw new IllegalStateException("栈已满,无法进栈,最大深度 " + DEFAULT_STACK_SIZE); } objects[++top] = t; } @Override public T peek() { if (isEmpty()) { return null; } T object = objects[top]; return object; } @Override public boolean isEmpty() { return top == -1; } @Override public void clear() { objects = (T[]) new Object[DEFAULT_STACK_SIZE]; top = -1; } @Override public int length() { return top; } } 测试代码为了实现创建的栈的测试,我们这里写了一个简单POJO对象,作为测试使用,也可以自己尝试创建一个对象
class Person { private String name; private int age; public Person() {} public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name=\'" + name + \'\\'\' + ", age=" + age + \'}\'; } }创建一个栈对象,使用其方法测试
public class TestBaseStack { public static void main(String[] args) { BaseStack<Person> stack = new BaseStack<>(); System.out.println("--------------------------循环新增测试--------------------------"); for (int i = 0; i < 8; i++) { Person person = new Person("姓名:" + i, i); stack.push(person); } System.out.println("新增栈元素完成 当前栈深度 = " +stack.length()); System.out.println("--------------------------测试满栈--------------------------"); try { stack.push(new Person("测试", 0)); } catch (IllegalStateException ex) { System.out.println(ex.getMessage()); } System.out.println("--------------------------循环测试出栈--------------------------"); while (stack.peek() != null) { // 获取栈顶元素出栈 System.out.println("出栈元素为 ------>" + stack.pop()); } // 新增栈元素 System.out.println("--------------------------新增栈元素测试--------------------------"); stack.push(new Person("测试账户",12)); // 显示入栈元素 System.out.println("栈顶元素为 ------>" + stack.peek()); System.out.println("--------------------------清空栈测试--------------------------"); System.out.println("当前栈是否为空 ------> " + stack.isEmpty()); stack.clear(); System.out.println("当前栈是否为空 ------> " + stack.isEmpty()); } } 测试效果可以看到实现了基本的栈的功能,后期我们将尝试使用Stack的应用场景.
--------------------------循环新增测试-------------------------- 新增栈元素完成 当前栈深度 = 7 --------------------------测试满栈-------------------------- 栈已满,无法进栈,最大深度 8 --------------------------循环测试出栈-------------------------- 出栈元素为 ------>Person{name=\'姓名:7\', age=7} 出栈元素为 ------>Person{name=\'姓名:6\', age=6} 出栈元素为 ------>Person{name=\'姓名:5\', age=5} 出栈元素为 ------>Person{name=\'姓名:4\', age=4} 出栈元素为 ------>Person{name=\'姓名:3\', age=3} 出栈元素为 ------>Person{name=\'姓名:2\', age=2} 出栈元素为 ------>Person{name=\'姓名:1\', age=1} 出栈元素为 ------>Person{name=\'姓名:0\', age=0} --------------------------新增栈元素测试-------------------------- 栈顶元素为 ------>Person{name=\'测试账户\', age=12} --------------------------清空栈测试-------------------------- 当前栈是否为空 ------> false 当前栈是否为空 ------> true