玩转数据结构 (第一章 数组)

首先我们可以通过java中的数组作为基础,来进行一系列的改造,创造我们自己的数组类型,例如增删改查,同时为了让我们的数组可以承载任意类型的元素,我们将使用泛型,也同时实现数组的可伸缩,让其更加灵活


public class Array<E> {
	private E[] data;
	private int Size;
	
	//构造函数,传入数组的容量capacity构造Array
	public Array(int capacity) {
		data = (E[]) new Object[capacity];
		Size = 0;
	}
	
	//无参构造器,默认数组的容量capacity=10
	public Array() {
		this(10);
	}
	
	//获取数组中元素的个数
	public int getSize() {
		return Size;
	}
	
	//获取数组的容量
	public int getcapacity() {
		return data.length;
	}
	
	//判断数组是否为空
	public boolean isEmpty() {
		return Size == 0;
	}
	
	//向所有元素最后一位添加新元素
	public void addLast(E e) {
		add(Size,e);
	}
	
	//向所有元素第一位添加一个新元素
	public void addFirst(E e) {
		add(0,e);
	}
	
	//在index位置插入一个新的元素
	public void add(int index, E e) {
		
		
		
			if(index < 0 || index > Size) {
				throw new IllegalArgumentException("add failed.Require index > 0 and index <= Size");
			}else {
				if(Size == data.length) {
					resize(2*data.length);
				}
				for(int i = Size -1 ; i >= index; i --) {
					data[i + 1] = data[i];
				}
				data[index] = e;
				Size ++;
			}
	}
	
	//获取index位置的元素
	E get(int index) {
		if(index < 0 || index >= Size) {
			throw new IllegalArgumentException("Get failed.Index is illegal.");
		}
		return data[index];
	}
	
	//获取第一个元素
	public E getFirst() {
		return get(0);
	}
	
	//获取最后一个元素
	public E getLast() {
		return get(Size - 1);
	}
	
	//修改index索引位置的元素
	void set(int index, E e) {
		if(index < 0 || index >= Size) {
			throw new IllegalArgumentException("Get failed.Index is illegal.");
		}
		data[index] = e;
	}
	
	//查找数组中是否有元素e
	public boolean contains(E e) {
		for(int i = 0; i < Size; i ++) {
			if (data[i] == e) {
				return true;
				}
		}
			return false;
	}
	
	
	//查找数组中元素e的索引,若是没有,返回-1
	public int find(E e) {
		for(int i = 0; i < Size; i ++) {
			if (data[i].equals(e)) {
				return i;
			}
		}
		return -1;
	}
	
	//从数组中删除index元素,并返回删除的元素
	public E remove(int index) {
		if(index < 0 || index >Size) {
			throw new IllegalArgumentException("Get failed.Index is illegal.");
		}
		E ret = data[index];
		for(int i = index +1; i < Size; i ++) {
			data[i -1 ] = data[i];
		}
		Size --;
		data[Size] = null;
		if(Size == data.length/4 && data.length/2 != 0) {
			resize(data.length/2);
		}
		return ret;
	}
	
	//从数组中删除第一个元素,并返回
	public E removeFirst() {
		return remove(0);
	}
	
	//从数组中删除最后一个元素,并返回
	public E removeLast() {
		return remove(Size-1);
	}
	
	//从数组中删除元素e,(如果没有就啥也不用干)
	public void removeElement(E e) {
		int index = find(e);
		if(index != -1)
			remove(index);
		
	}
	
	@Override
	public String toString() {
		StringBuilder res = new StringBuilder();
		res.append(String.format("Array Size = %d capacity = %d\n", Size,data.length));
		res.append("[");
		for(int i =0; i < Size; i ++) {
			res.append(data[i]);
			if(i != Size-1) {
				res.append(",");
			}
		}
		res.append("]");
		
		return res.toString();
	}
	
	//对数组实现容量伸缩
	private void resize(int newCapacity) {
		E[] newData = (E[]) new Object[newCapacity];
		for(int i =0; i < Size; i ++) {
			newData[i] = data[i];
		}
		data = newData;
	}
	
}

在对这个复杂度的分析中,我们应该取最坏的进行分析,当然最坏的可能发生概率很小,此时我们可以进行均摊复杂度分析,这样更加适合,同时在以上的数组扩容的操作中,我们需要注意一个问题,那就是复杂度的震荡,我们应该选择适当的数组容量伸缩的时机来防止这个问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值