假定集合 S 由 n 个元素组成,它们按照线性次序存放,于是我们就可以直接访问其中的第一个 元素、第二个元素、第三个元素……。也就是说,通过[0, n-1]之间的每一个整数,都可以直接访问 到唯一的元素 e,而这个整数就等于 S 中位于 e 之前的元素个数⎯⎯在此,我们称之为该元素的秩 (Rank)。不难看出,若元素 e 的秩为 r,则只要 e 的直接前驱(或直接后继)存在,其秩就是 r-1 (或 r+1)。这一定义与 Java、C++之类的程序语言中关于数组元素的编号规则是一致的。
基于数组,可以直接实现向量 ADT。我们借用一个数组 A[],其中 A[i]分别存放一个引用,指向 秩为 i 的向量元素。为此,A[]的容量 N 需要足够大,还需要设置一个实例变量 n 指示向量的实际规模。
public class ArrayVector<E> implements Vector<E>{
//数组的容量
private final int DEFAULT_CAPACITY = 1024;
//向量的实际规模
private int size = 0;
//对象数组
private Object[] elementData;
public ArrayVector() {
this.elementData = new Object[DEFAULT_CAPACITY];
this.size=0;
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return 0 == size;
}
@Override
public E getAtRank(int r) throws ExceptionBoundaryViolation {
if (0 > r || r >= size) {
throw new ExceptionBoundaryViolation("意外:秩越界");
}
return elementData(r);
}
@Override
public E replaceAtRank(int r, E obj) throws ExceptionBoundaryViolation {
if (0 > r || r >= size) {
throw new ExceptionBoundaryViolation("意外:秩越界");
}
E oldEle = elementData(r);
elementData[r] = obj;
return oldEle;
}
@Override
public E insertAtRank(int r, E obj) throws ExceptionBoundaryViolation {
if (0 > r || r >= DEFAULT_CAPACITY) {
throw new ExceptionBoundaryViolation("意外:秩越界");
}
if (size >= DEFAULT_CAPACITY){
throw new ExceptionBoundaryViolation("意外:数组溢出");
}
//后续元素顺次后移
System.arraycopy(elementData, r, elementData, r + 1, size - r);
//插入
elementData[r] = obj;
//更新当前规模
size++;
return obj;
}
@Override
public E removeAtRank(int r) throws ExceptionBoundaryViolation {
if (0 > r || r >= size) {
throw new ExceptionBoundaryViolation("意外:秩越界");
}
E bak = elementData(r);
//后续元素顺次前移
System.arraycopy(elementData, r + 1, elementData, r, size - r);
size--;//更新当前规模
return bak;
}
E elementData(int index) {
return (E) elementData[index];
}
}