栈
LIFO
接口
public interface IStack<Item> extends Iterable<Item> {
/**
* 添加一个元素
*
* @param item
* 元素
*/
void push(Item item);
/**
* 删除最近添加的元素并返回它
*
* @return 元素
*/
Item pop();
/**
* 返回是否为空
*
* @return boolean
*/
boolean isEmpty();
/**
* 返回元素的数量
*
* @return 数量
*/
int size();
}
Test
import org.junit.Before;
import org.junit.Test;
import edu.princeton.cs.algs4.StdOut;
public abstract class AbstractStackTest<T extends IStack<String>> {
private T instance;
protected abstract T createInstance();
@Before
public void setUp() {
instance = createInstance();
}
@Test
public void testMain() {
String[] strings = new String[] {"out", "first", "in", "last"};
for (int i = 0; i < strings.length; i++) {
instance.push(strings[i]);
}
StdOut.println("遍历栈: ");
for (String s : instance) {
StdOut.println(s);
}
StdOut.println("遍历栈结束");
while (!instance.isEmpty()) {
StdOut.print(instance.pop() + " ");
}
StdOut.println("(" + instance.size() + " left on stack)");
}
}
数组实现
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* 下压(LIFO)栈;能够动态调整数组大小的实现
* - 每项操作的用时都与集合的大小无关
* - 空间需求总是不超过集合大小乘以一个常数
* 缺点: 某些 push() 和 pop() 操作会调整数组的大小,这项操作的耗时和栈大小成正比
*
*/
public class ResizingArrayStack<Item> implements IStack<Item> {
private Item[] a;
private int size;
ResizingArrayStack(int cap) {
// 泛型在Java中不可以直接实例化
// 所以这里使用了强制转型
// Java 底层也是如此实现的
a = (Item[])new Object[cap];
}
@Override
public void push(Item item) {
boolean isFull = isFull();
if (isFull) {
// 如果栈满了,将栈扩容一倍
resize(size * 2);
}
a[size++] = item;
}
/**
* 调整数组的大小
*
* @param max
* 新的数组大小
*/
private void resize(int max) {
// 实现逻辑为将栈移动到另一个大小不同的数组中
Item[] temp = (Item[])new Object[max];
for (int i = 0; i < size; i++) {
temp[i] = a[i];
}
a = temp;
}
/**
* 返回栈是否已满
*
* @return boolean
*/
private boolean isFull() {
return size >= a.length;
}
@Override
public Item pop() {
Item item = a[--size];
// 删除它
a[size] = null;
// 当栈大小小于数组的四分之一,将数组大小减半
// 保证数组半满,下次需要改变数组大小之前仍能进行多次的 push() 和 pop()
if (size > 0 && size <= a.length / 4) {
resize(a.length / 2);
}
return item;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public int size() {
return size;
}
@Override
public Iterator<Item> iterator() {
return new ReverseArrayIterator();
}
/**
* 倒叙遍历迭代器
*
*/
public class ReverseArrayIterator implements Iterator<Item> {
/**
* 嵌套类可以访问包含它的类的实例变量(size)
*/
private int i = size;
@Override
public boolean hasNext() {
return i > 0;
}
@Override
public Item next() {
if (i <= 0) {
throw new NoSuchElementException("已经没有元素可以迭代!");
}
// 嵌套类可以访问包含它的类的实例变量(a)
return a[--i];
}
@Override
public void remove() {
throw new UnsupportedOperationException("不支持remove操作!");
}
}
}
链表实现
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.inkparker.structs.IStack;
public class LinkedStack<Item> implements IStack<Item> {
/**
* 栈顶;最近添加的元素
*/
private Node first;
/**
* 元素数量
*/
private int size;
/**
* 节点的嵌套类
*/
private class Node {
Item item;
Node next;
}
@Override
public void push(Item item) {
Node oldFirst = this.first;
first = new Node();
first.item = item;
first.next = oldFirst;
size++;
}
@Override
public Item pop() {
Item item = first.item;
first = first.next;
size--;
return item;
}
@Override
public boolean isEmpty() {
return first == null;
}
@Override
public int size() {
return size;
}
@Override
public Iterator<Item> iterator() {
return new ListIterator();
}
private class ListIterator implements Iterator<Item> {
private Node current = first;
@Override
public boolean hasNext() {
return current != null;
}
@Override
public Item next() {
if (current == null) {
throw new NoSuchElementException("没有元素可供遍历了!");
}
Item item = current.item;
current = current.next;
return item;
}
@Override
public void remove() {
throw new UnsupportedOperationException("不支持 remove !");
}
}
}