线性表的数组实现,其内部存放数据的实际上就是一个可变容量的数组,大家都知道数组的特性,获取数组中I的数据的时间为常数,所以做查询非常快。
在ArrayList类中一共有4个成员变量,其中elements数组及size用于存储线性表中的数据元素及元素个数,strategy完成线性表中原色的比较操作策略;LEN是elements的初始默认大小,数组的大小再后续的插入操作中可以发生变化。
算法getSize(), isEmpty(), replate(int i, Object e),get(i)的时间复杂度为1,由于数组的随机存取特性,因此,获取线性表中序号为i的原色或对其进行替换均可在常数时间内完成,通过size可以直接判断出线性表中元素个数和线性表是否为空。
算法contains(Object e), indexOf(Object e)主要是查找线性表中的某个元素,查找会出现不成功的情况,在整个查找过程中会比较接近一半的元素。
算法insert(int i, Object e), remove(i)主要按照序号来完成线性表的插入与删除操作,时间复杂度上面已经说明,为常数,除此之外在找到元素以后要进行相应操作会移动一半的数据元素,特别的在插入过程中还会出现空间扩展,采用平均时间分析后,算法消耗的时间为n/2。
算法insertBefore(Object obj, Object e),insertAfter(Object obj, Object e), remove(Object e),按照线性表中特定的元素来完成元素的插入,删除,操作,此时算法分别为先在线性表中找到对应的数据元素,然后在进行相应操作。在使用数组实现是运行时间为n。
除此之外我们还可以看到两个东西size和数组的elements.lengh,在此结构中要注意size <= elements.lengh,length为开辟的存储空间,size为空间中实际存放的元素数量,开辟了空间不一定要存放元素。
package taxus.list;
public class ListArray implements List{
private final int LEN = 5;
private int size;
private Object[] elements;
private Strategy strategy;
public ListArray(){
this(new DefaultStrategy());
}
public ListArray(Strategy strategy){
this.strategy = strategy;
size = 0;
elements = new Object[LEN];
}
public int getSize() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public boolean contains(Object e) {
for (int i = 0; i < size; i++) {
if (strategy.equal(elements[i], e)) {
return true;
}
}
return false;
}
public int indexOf(Object e) {
for (int i = 0; i < size; i++) {
if (strategy.equal(elements[i], e)) {
return i;
}
}
return -1;
}
public void insert(int i, Object e) throws OutOfBoundaryException {
if (i < 0 || i > size) {
throw new OutOfBoundaryException("指定的插入序号越界,Size:" + size + " Index:" + i);
}
if (i >= elements.length) {
expandSpace();
}
for (int j = size; j > i; j--) {
elements[j] = elements[j-1];
}
elements[i] = e;
size++;
return;
}
private void expandSpace(){
Object[] a = new Object[elements.length * 2];
for (int i = 0; i < elements.length; i++) {
a[i] = elements[i];
}
elements = a;
}
public boolean insertBefore(Object obj, Object e) {
int i = indexOf(obj);
if (i < 0) {
return false;
}
insert(i, e);
return true;
}
public boolean insertAfter(Object obj, Object e) {
int i = indexOf(obj);
if (i < 0) {
return false;
}
insert(i + 1, e);
return true;
}
/**
* size length
* size实际大小
* length 创建的空间大小
* length >= size, 插入时size范围内安全,超出size有可能就超越length,删除时删除size范围内,
*/
public Object remove(int i) throws OutOfBoundaryException {
if (i < 0 || i > size) {
throw new OutOfBoundaryException("指定的插入序号越界,Size:" + size + " Index:" + i);
}
Object obj = elements[i];
for (int j = i; j < size - 1; j++) {
elements[j] = elements[j];
}
elements[--size] = null;
return obj;
}
public boolean remove(Object e) {
int i = indexOf(e);
if (i < 0) {
return false;
}
remove(i);
--size;
return true;
}
public Object replace(int i, Object e) throws OutOfBoundaryException {
if (i < 0 || i > size) {
throw new OutOfBoundaryException("指定的插入序号越界,Size:" + size + " Index:" + i);
}
Object old = elements[i];
elements[i] = e;
return old;
}
public Object get(int i) throws OutOfBoundaryException {
if (i < 0 || i > size) {
throw new OutOfBoundaryException("指定的插入序号越界,Size:" + size + " Index:" + i);
}
return elements[i];
}
public int getElementsLength(){
return elements.length;
}
}
在ArrayList类中一共有4个成员变量,其中elements数组及size用于存储线性表中的数据元素及元素个数,strategy完成线性表中原色的比较操作策略;LEN是elements的初始默认大小,数组的大小再后续的插入操作中可以发生变化。
算法getSize(), isEmpty(), replate(int i, Object e),get(i)的时间复杂度为1,由于数组的随机存取特性,因此,获取线性表中序号为i的原色或对其进行替换均可在常数时间内完成,通过size可以直接判断出线性表中元素个数和线性表是否为空。
算法contains(Object e), indexOf(Object e)主要是查找线性表中的某个元素,查找会出现不成功的情况,在整个查找过程中会比较接近一半的元素。
算法insert(int i, Object e), remove(i)主要按照序号来完成线性表的插入与删除操作,时间复杂度上面已经说明,为常数,除此之外在找到元素以后要进行相应操作会移动一半的数据元素,特别的在插入过程中还会出现空间扩展,采用平均时间分析后,算法消耗的时间为n/2。
算法insertBefore(Object obj, Object e),insertAfter(Object obj, Object e), remove(Object e),按照线性表中特定的元素来完成元素的插入,删除,操作,此时算法分别为先在线性表中找到对应的数据元素,然后在进行相应操作。在使用数组实现是运行时间为n。
除此之外我们还可以看到两个东西size和数组的elements.lengh,在此结构中要注意size <= elements.lengh,length为开辟的存储空间,size为空间中实际存放的元素数量,开辟了空间不一定要存放元素。