编程语言
960
Stack是Java中常用的数据结构之一,Stack具有"后进先出(LIFO)"的性质。 只能在一端进行插入或者删除,即压栈与出栈
栈的实现比较简单,性质也简单。可以用一个数组来实现栈结构。
- 入栈的时候,只在数组尾部插入
- 出栈的时候,只在数组尾部删除**
我们来看一下Stack的用法 :如下
public static void main(String[] args){ //新建一个栈 Stack<String> stack = new Stack<>(); //分别向栈中添加不同的元素 stack.push("tom"); stack.push("jim"); stack.push("wendy"); stack.push("natasha"); //分别弹栈 System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); }
输出如下:
natasha wendy jim tom
从输出可以看到,最后入栈的,最先出栈
下面我们底层用数组也来实现这样一个栈,在数组的尾部插入和删除。 也就是入栈和出栈。如下图:
完整的源码如下:
public class QStack<E> { //数组的默认大小为10 private static final int DEFAULT_INIT_CAPACITY = 10; //底层的数组 private Object[] elements; //栈中的个数 private int size; public QStack() { this(DEFAULT_INIT_CAPACITY); } public QStack(int capacity) { //capacity条件检查 ,这里我们直接抛出异常 if (capacity <= 0) { throw new IllegalArgumentException("capacity <= 0"); } if (capacity > Integer.MAX_VALUE) { throw new IllegalArgumentException("capacity > Integer.MAX_VALUE"); } //新建一个capacity大小的数组 elements = new Object[capacity]; //初始个数为0 size = 0; } //栈是否为空 public boolean isEmpty() { return size == 0; } //返回栈中的元素个数 public int size() { return size; } //将一个元素压入栈中 public E push(E e) { //如果栈已满,进行扩容 if (size >= elements.length) { grow(); } //扩容完后将元素e压入栈中 elements[size] = e; //别忘了size需要加 1 size++; return e; } //出栈,就是将数组最后一个元素弹出 public E pop() { //如果栈为空就返回null if (isEmpty()) { return null; } //拿到栈的大小 int len = size(); //把数组中最后一个元素保存起来 E e = peek(); //个数别忘了减1 size--; //将最后一个元素置null elements[len - 1] = null; //返回e return e; } //返回最后一个元素 public E peek() { int len = size(); if (len == 0) throw new RuntimeException("stack is empty"); return (E) elements[len - 1]; } //扩容 private void grow() { //将之前的数组保存 int oldCapacity = elements.length; Object[] old = elements; //新的数组大小为原来数组大小的2倍 int newCapacity = oldCapacity * 2; //再新建一个大小为原来数组2倍的新数组 elements = new Object[newCapacity]; //把以前的老的数组中的元素都移动新数组中 for (int i = 0; i < oldCapacity; i++) { elements[i] = old[i]; } //释放以前的内存空间 old = null; } }
以上面可知:用数组实现栈结构,主要需要注意以下 2 点:
- 在数组的尾部插入和删除,也就是压栈和弹栈
- 由于是用数组实现栈结构,数组满的时候,需要扩容
下面我们写一段测试代码来测试,如下:
public static void main(String[] args){ //创建一个栈 QStack<String> stack = new QStack<>(); //分别向栈中压入4个不同的元素 stack.push("tom"); stack.push("jim"); stack.push("wendy"); stack.push("natasha"); //分别弹栈 System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); }
打印如下:
natasha wendy jim tom