栈是限制插入和删除都只能在一个位置的表,该位置是表的末端,叫做栈顶(top)。对栈的基本操作有入栈(push)和出栈(pop),入栈操作相当于将一个元素插入到栈中,出栈操作相当于删除栈顶的元素,并返回。
栈又叫做LIFO(后进先出)表。栈的一般模型是,存在某个元素位于栈顶,而该元素又是唯一可访问的元素。
由于栈也是表,所以我们可以用数组或者链表来实现一个栈。
链表实现栈
Item为泛型,表示可以存储任意类型的数据。
API:
boolean isEmpty()//判断栈是否为空
int size()//获取栈中元素数量
boolean push(Item item) //压栈
Item pop()//出栈
Iterator iterator()//获取迭代器
import java.util.Iterator;
import java.util.NoSuchElementException;
public class MyStack<Item> implements Iterable<Item> {
private Node top;//栈顶
private int size;//栈中元素数量
//节点内部类
private class Node{
Item item;//数据元素
Node next;//next链
}
//判断栈是否为空
public boolean isEmpty() {
return size() == 0;
}
//获取栈中元素数量
public int size() {
return size;
}
//压栈
public boolean push(Item item) {
Node oldTop = top;//创建一个节点保存当前top节点
top = new Node();//创建一个新新的top节点
top.item = item;//将数据保存到新top节点中
top.next = oldTop;//将新的top节点next链指向原top节点
size++;
return true;
}
//出栈
public Item pop() {
//判断是否为空,对空栈做出栈操作则抛异常
if(isEmpty()) {
throw new NoSuchElementException();
}
Item item = top.item;
top = top.next;
size--;
return item;
}
//获取迭代器
public Iterator<Item> iterator() {
// TODO Auto-generated method stub
return new StackIterator();
}
//迭代器内部类
private class StackIterator implements Iterator<Item> {
private Node current = top;
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return current != null;
}
@Override
public Item next() {
// TODO Auto-generated method stub
Item item = current.item;
if(!hasNext()) {
throw new NoSuchElementException();
}
current = current.next;
return item;
}
}
}
简单测试用例:
public class Test {
public static void main(String[] args) {
MyStack<Integer> myStack = new MyStack<Integer>();
System.out.println("是否为空:" + myStack.isEmpty());
System.out.println("元素数量:" + myStack.size());
myStack.push(0);
myStack.push(1);
myStack.push(2);
myStack.push(3);
myStack.push(4);
myStack.push(5);
System.out.println("出栈:" + myStack.pop());
System.out.println("出栈:" + myStack.pop());
System.out.println("出栈:" + myStack.pop());
System.out.println("出栈:" + myStack.pop());
System.out.println("出栈:" + myStack.pop());
System.out.println("出栈:" + myStack.pop());
}
}