先来看一个生活场景:乘坐垂直电梯
先定一个规矩:进入电梯的每个人尽量电梯里面走。
那么就会出现:最先进入电梯的人最后出电梯(在到达相同楼层的情况下);
栈就是这样一种结构:
Java类库中提供了Stack类来实现栈,并且是范型类可以存储不同的数据结构,Stack 类方法:
boolean empty() :栈是否为空
Object peek( ) :查看栈顶元素
Object pop( ) :移除栈顶元素
Object push(Object obj) :添加元素
int search(Object element) : 自顶向下查找元素
import java.util.Stack; public class Test { public static void main(String[] args) { System.out.println("Integer 类型:"); Stack<Integer> st = new Stack<Integer>(); st.push(1); st.push(2); System.out.println("添加元素之后 栈顶元素:" +st.peek()+ " 是否为空:"+st.empty()+" 栈1内所有元素:" + st); st.pop(); st.pop(); System.out.println("移除元素之后"); System.out.println("是否为空:"+st.empty()); System.out.println(); System.out.println("自定义 类型:"); Stack<MyObj> so = new Stack<MyObj>(); so.push(new MyObj(3,"自定义对象3")); so.push(new MyObj(4,"自定义对象4")); System.out.println("添加元素之后 栈顶元素:" +so.peek().name+ " 是否为空:"+so.empty()); so.pop(); so.pop(); System.out.println("移除元素之后"); System.out.println("是否为空:"+so.empty()); } } class MyObj{ Integer id; String name; MyObj(int id,String name){ this.id=id; this.name=name; } }
两种栈的实现方式:
用数组实现栈:只需要定义一个栈顶指针指向栈顶元素即可,当要添加数据时指针往后移动,当要删除数据时指针往前移动。
在入栈的时候如果栈已经满了,那么拓展内存,在出栈的时候如果栈为空返回null;
import java.util.Arrays; //范型类型、创建的时候指定数据类型 public class ArrayStack<E> { private Object[] stack; private int index; ArrayStack() { stack = new Object[10]; index = 0; //栈顶地址 } public boolean isEmpty() { return index == 0; } public E peek() { if (isEmpty()) { return null; } return (E)stack[index-1]; } public E pop() { if (isEmpty()) { return null; } index--; return (E)stack[index]; } //拓展内存 private void ensureCapacity(int index) { if (index > stack.length) { int len = stack.length + 10; stack = Arrays.copyOf(stack, len); } } public E push(E e) { ensureCapacity(index+1); stack[index++] = e; return e; } public static void main(String[] args) { ArrayStack<String> stack = new ArrayStack<>(); stack.push("a"); stack.push("b"); System.out.println("栈顶元素:"+stack.peek()); System.out.println("栈顶元素出栈:"+stack.pop()); System.out.println("栈顶元素出栈:"+stack.pop()); System.out.println("栈顶元素出栈:"+stack.pop()); } }
链表实现栈结构:当添加节点的时候栈顶元素为新添加的节点,该节点的next指向之前的节点,当删除元素时候当前节点指向下一个节点即可
//链表数据结构 class Node<E> { Node<E> next = null; E data; public Node(E data) { this.data = data; } } //链表实现栈数据结构 public class ListNodeStack<E> { Node<E> top = null; boolean isEmpty() { return top == null; } public void push(E item) { Node<E> node = new Node<E>(item); node.next = top; top = node; } public E pop() { if (this.isEmpty()) return null; E data = top.data; top = top.next; return data; } public E peek() { if (this.isEmpty()) return null; return top.data; } public static void main(String[] args) { ListNodeStack<Integer> stack = new ListNodeStack<>(); System.out.println("入栈"); stack.push(1); stack.push(2); System.out.println("出栈:"+stack.pop()); System.out.println("出栈:"+stack.pop()); System.out.println("栈为空?"+stack.isEmpty()); } }