1.为什么是N == a.length/4 ?
因为我们调整大小的时候使用的是加倍和减半,在减半时,已使用的量控制在四分之一,那么减半后还可以有足够的空间来压栈操作。这种数组大小的调整是综合考虑的结果 既不会溢出利用率也不会低于1/4 。
// 下压栈 动态调整数组大小
import java.util.Iterator;
public class ResizingArrayStack<Item> implements Iterable<Item>
{
private Item[] a = (Item[]) new Object[1];
private int N = 0;
public boolean isEmpty() { return N == 0;}
public int size() { return N;}
//resize函数 使变成大小为max的数组
public void resize(int max)
{
//生成泛型数组大小为max
Item[] temp = (Item[]) new Object[max];
//数组每个元素复制到temp这个泛型数组中
for(int i = 0; i < N; i++)
{
temp[i] = a[i];
}
//a指向了temp,这时候a就是大小为max且前N个元素为原来元素的数组了
a = temp;
}
public void push(Item item)
{
//满了 加倍
if(N == a.length-1) resize(2*a.length);
a[N++] = item;
}
public Item pop()
{
Item item = a[--N];
a[N] = null;//避免对象游离问题 这个时候a[N]已经出栈了 不需要了 所以是游离的额
//长度不为0 且 N长度为a数组长度的四分之一时 调整大小为二分之一
if(N > 0 && N == a.length/4) resize(a.length/2);
return item;
}
//iterator方法 返回一个迭代器ResizingArrayIterator
@override
public Iterator<Item> iterator()
{ return new ResizingArrayIterator();}
//构造这个迭代器
private class ReverseArrayIterator implements Iterator<Item>
{
private int i = N;
public boolean hasNext() { return i > 0;}
public Item next() {return a[--i];}
public void remove() {}
}
}
/*
优点:每项操作的用时都与集合大小无关
空间需求总是不超过集合大小乘以一个常数
缺点:push() pop() 操作会调整数组的大小,耗时与栈大小成正比
*/