什么是数据结构
二次封装java中的数组
- 索引没有语意,如何表示没有元素。
- 如何添加元素?如何删除元素?
数据结构实现
- size属性的位置就是将要添加元素的位置
public class Array<E> {
// 设置一个int类型的数组
private E[] arr;
private int size;
public Array(int capacity) {
// arr = new int[capacity];
arr = (E[]) new Object[capacity];
}
public Array() {
this(10);
}
// 获取元素实际个数
public int getSize() {
return size;
}
// 获取数组容量
public int getCapacity() {
return this.arr.length;
}
// 判断数组是否为空
public boolean isEmpty() {
return size == 0;
}
// 添加元素。注意size的位置不能出现值的
public void add(int index, E element) {
// this.arr[index] = element;
// size++;
// 1. 先判断填入的元素是否已满
if(size == arr.length) {
// throw new Error("add fail, size == arr.length");
// 扩容为原来的2倍
resize(arr.length * 2);
}
// 2. 判断填入的元素位置是否越界。这里我们判断越界使用size。不想要稀疏数组。
if(index > size || index < 0) throw new Error("add fail, index > size || index < 0");
// 3. 开始插入元素,开始向后推移
for(int i = size - 1; i >= index; i--) {
// 这里刚好利用size位置存入空值的特性。
arr[i + 1] = arr[i];
}
// 4. index的位置已无元素,插入元素
arr[index] = element;
size++;
}
// 在最后添加元素
public void addLast(E element) {
add(size, element);
}
// 在最开始添加元素
public void addFirst(E element) {
add(0, element);
}
// toString
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append(String.format("Array capacity %d, Array size %d\n", arr.length, size));
res.append("[");
for(int i = 0; i < size; i++) {
res.append(arr[i]);
if(i != size - 1) {
res.append(",");
}
}
res.append("]");
return res.toString();
}
// 获取元素
public E get(int index) {
if(index < 0 || index >= size) throw new Error("get fail, index < 0 || index >= size");
return arr[index];
}
// 修改元素
public void set(int index, E element) {
if(index < 0 || index >= size) throw new Error("get fail, index < 0 || index >= size");
arr[index] = element;
}
// 判断是否包含元素
public boolean contains(E element) {
for(int i = 0; i < size; i++) {
if(element == arr[i]) {
return true;
}
}
return false;
}
// 查找元素下表
public int find(E element) {
for(int i = 0; i < size; i++) {
if(element == arr[i]) {
return i;
}
}
return -1;
}
// 删除元素
public boolean remove(int index) {
if(index < 0 || index >= size) {
throw new Error("delete fail, index < 0 || index >= size");
}
for(int i = index; i < size; i++) {
arr[i] = arr[i + 1];
}
size--;
// 这里为了防止扩容震荡,所以size 等于容积的1/4时,在缩容
if(size == arr.length / 4 && data.length / 2 != 0) {
// 缩容为原来的一半。
resize(arr.length / 2);
}
return true;
}
// 删除最后一个元素
public boolean removeLast() {
return remove(size - 1);
}
// 删除第一个元素
public boolean removeFirst() {
return remove(0);
}
// 扩容
public void resize(int capacity) {
// 1. 先遍历原数组,并取出元素。
E[] newArr = (E[]) new Object[capacity];
for(int i = 0; i < size; i++) {
newArr[i] = arr[i];
}
arr = newArr;
newArr = null;
}
}
数据结构复杂度分析
基本方法
扩容方法
这里会引起不断地扩容和降容。出现复杂度震荡。所以我们可以改变降容的条件。不让其size = arr.length / 2 时就开始降容。而是size = arr.length / 4。