-
栈是一种先进后出的数据结构,是一种只能在一端进行插入和删除操作的线性表。
-
它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。
-
数据进入到栈的动作为压栈(入栈),数据从栈中出去的动作为出栈。
-
原理图:
-
栈是一种逻辑结构,具体存储实现是考虑物理存储结构,即顺序存储结构(数组)和链式存储结构(链表)。
-
链表实现栈:
import java.util.Iterator; /** * @author JIN * @description 栈 **/ public class Stack<T> implements Iterable<T>{ //头节点 private Node head; //栈内个数 private int N; public Stack(){ head = new Node(null,null); N = 0; } //判断是否为空 public boolean isEmpty(){ return N == 0; } //返回栈中个数 public int size(){ return N; } //入栈 public void push(T t){ //栈后进的元素是在前面,因此使用头插法。 head.next = new Node(t,head.next); N++; } //出栈 public T pop(){ Node node = head.next; //安全性校验 // 若没有这个校验,栈中若没有元素,即node == null //此时node.next将是空指针异常 if(node == null){ return null; } //把第一个元素取出,并让头节点指向第二个节点。 head.next = node.next; N--; return node.data; } class Node{ private T data; private Node next; public Node(T data, Node next){ this.data = data; this.next = next; } } @Override public Iterator<T> iterator() { return new Iterator<T>() { private Node node = head; @Override public boolean hasNext() { return node.next != null; } @Override public T next() { node = node.next; return node.data; } }; } }
-
数组实现栈:
import java.util.Iterator; /** * @author JIN * @description 栈 **/ public class Stack2<T> implements Iterable<T>{ //数组用于模拟栈 private T[] data; //实际存储的个数 private int N; //数组的容量 private int size; //默认构造函数,初始化数组大小为4 public Stack2(){ this(4); } //构造函数,可以设置数组大小 public Stack2(int size){ //因为是泛型,不能 new T[size]; //因此只能先new Object再强转 this.data = (T[])new Object[size]; this.size = size; N = 0; } //判断是否为空 public boolean isEmpty(){ return N == 0; } //返回存储的个数 public int size(){ return N; } //入栈 public void push(T t){ //扩容 if(N > size/2){ size = size<<1; resize(size); } //入栈 data[N++] = t; } //扩容 public void resize(int size){ //存储旧数据 T[] olddata = data; this.data = (T[]) new Object[size]; //把旧数据复制到新数组上 for(int i = 0; i < N; i++){ data[i] = olddata[i]; } } //出栈 public T pop(){ //若无数据,直接返回 if(N <= 0){ return null; } //若数组大小有100,但是实际存储数据只有2个,那太浪费空间了 //因此进行缩容,但若频繁扩容缩容会使整体性能下降 if(N < size/4){ size = size>>1; resize(size); } return data[--N]; } @Override public Iterator<T> iterator() { return new Iterator<T>() { private int num = N; @Override public boolean hasNext() { return num > 0; } @Override public T next() { return data[--num]; } }; } }