背包
背包是一种只存不取的数据结构
接口
public interface IBag<Item> extends Iterable<Item> {
/**
* 添加元素
*
* @param item
* 元素
*/
void add(Item item);
/**
* 返回是否为空
*
* @return boolean
*/
boolean isEmpty();
/**
* 返回背包中元素的数量
*
* @return 数量
*/
int size();
}
Test
使用抽象Test类对接口进行测试
import org.junit.Before;
import org.junit.Test;
import edu.princeton.cs.algs4.StdOut;
public abstract class AbstractBagTest<T extends IBag<Double>> {
private T instance;
protected abstract T createInstance();
@Before
public void setUp() {
instance = createInstance();
}
@Test
public void testMain() {
for (int i = 0; i < 100; i++) {
instance.add(Math.random());
}
int size = instance.size();
double sum = 0.0;
for (Double x : instance) {
sum += x;
}
double mean = sum / size;
sum = 0.0;
for (Double x : instance) {
sum += (x - mean) * (x - mean);
}
double std = Math.sqrt(sum / (size - 1));
StdOut.printf("Mean: %.2f\n", mean);
StdOut.printf("Std dev: %.2f\n", std);
}
}
数组实现
import java.util.Iterator;
import java.util.NoSuchElementException;
public class ResizingArrayBag<Item> implements IBag<Item> {
private Item[] a;
private int size;
ResizingArrayBag(int cap) {
a = (Item[])new Object[cap];
}
@Override
public void add(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 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;
public class LinkedBag<Item> implements IBag<Item> {
/**
* 栈顶;最近添加的元素
*/
private Node first;
/**
* 元素数量
*/
private int size;
/**
* 节点的嵌套类
*/
private class Node {
Item item;
Node next;
}
@Override
public void add(Item item) {
Node oldFirst = this.first;
first = new Node();
first.item = item;
first.next = oldFirst;
size++;
}
@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 !");
}
}
}