数据结构是算法的基础和计算机应用的基础,第一个实现的是动态数组,对应于Java的ArrayList,没有它做得那么好,但对于底层实现原理可以有一个初步掌握。以下是具体代码实现:
//此数组类支持泛型
public class Array<E> {
private E[] data; //声明保存数据的数组
private int size; //声明数组的大小即存储了多少个元素
//有参构造函数需要提供数组初始容量,即数组能够装多少个元素
public Array(int capacity) {
data = (E[])new Object[capacity]; //根据参数开辟相应空间的数组
size = 0; //初始大小为0
}
public Array() { //无参构造函数默认数组容量为10
this(10);
} public Array(E[] arr) { //有参构造函数,以输入素组生成生成数组
data = (E[])new Object[arr.length];
for(int i = 0; i < arr.length; i++)
data[i] = arr[i];
size = arr.length;
}
//获取数组大小
public int getSize() {
return size;
}
//获取数组容量
public int getCapacity() {
return data.length;
}
//判断数组是否为空
public boolean isEmpty() {
return size == 0;
}
//添加元素,根据索引,将指定元素插到相应位置,支持动态添加
public void add(int index, E e) {
//判断索引合法性
if(index < 0 || index > size)
throw new IllegalArgumentException("Add failed.Require index >=0 and index <= size.");
//如果数组尺寸等于数组容量,表明数组已满,需要扩容,大小为现在容量的2倍
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++; //维护size,添加一个元素需要加1
}
//向数组末端添加一个元素
public void addLast(E e) {
add(size, e);
}
//向数组头部添加一个元素
public void addFirst(E e) {
add(0, e);
}
//根据索引获取元素
public E get(int index) {
if(index < 0 || index >=size)
throw new IllegalArgumentException("Get failed.Index is illegal.");
return data[index];
}
//根据索引修改元素值
public void set(int index, E e) {
if(index < 0 || index >=size)
throw new IllegalArgumentException("Set failed.Index is illegal.");
data[index] = e;
}
//判断数组中是否包含输入的元素
public boolean contain(E e) {
//遍历整个数组,判断数组中元素是否与输入元素相等
for(int i = 0; i < size; i++) {
if(data[i].equals(e))
return true;
}
return false;
}
//根据输入元素查找下表值
public int find(E e) {
for(int i = 0; i < size; i++) {
if(data[i].equals(e))
return i;
}
return -1;
}
//根据索引删除相应元素
public E remove(int index) {
if(index < 0 || index >=size)
throw new IllegalArgumentException("Remove failed.Index is illegal.");
E ret = data[index]; //保存待删的元素
//从需要删除的元素下一个开始遍历,元素往前挪一格
for(int i = index + 1; i < size; i++) {
data[i - 1] = data[i];
}
size--; //维护size,需要减一个
data[size] = null;
//如果数组元素减少到容量的1/4,可以将数组容量缩减为容量1/2
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);
}
//根据相应的元素的值删除元素
public void removeElement(E e) {
int index = find(e);
if(index != -1)
remove(index);
}
//重写toStirng方法,方便观察
@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;
} //交换数组中两个元素位置
public void swap(int i, int j) {
//判断索引合法性
if(i < 0 || i >= size || j < 0 || j >= size)
throw new IllegalArgumentException("Index is illegal.");
//实施交换
E temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
下面是测试程序
public class Main {
public static void main(String[] args) {
Array<Integer> arr = new Array<>();
for(int i = 0; i < 10; i++) {
arr.addLast(i);
}
System.out.println(arr);
arr.add(1, 100);
System.out.println(arr);
arr.addFirst(-1);
System.out.println(arr);
arr.remove(2);
System.out.println(arr);
arr.removeElement(4);
System.out.println(arr);
arr.removeFirst();
System.out.println(arr);
}
}
结果为:
Array: size = 10, capacity = 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array: size = 11, capacity = 20
[0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array: size = 12, capacity = 20
[-1, 0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array: size = 11, capacity = 20
[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array: size = 10, capacity = 20
[-1, 0, 1, 2, 3, 5, 6, 7, 8, 9]
Array: size = 9, capacity = 20
[0, 1, 2, 3, 5, 6, 7, 8, 9]
其他结果就不一一测试,能够实现ArrayList基本功能