数据结构学习-线性表的数组实现LIstArray

数据结构学习---线性表的数组实现LIstArray
  线性表的数组实现,其内部存放数据的实际上就是一个可变容量的数组,大家都知道数组的特性,获取数组中I的数据的时间为常数,所以做查询非常快。
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为空间中实际存放的元素数量,开辟了空间不一定要存放元素。