数据结构java-数组
1、了解
<1> 用来存储一组类型相同的数据
<2> 分配连续的空间,创建指定容量(大小)
<3> 创建int[] arr = new int[10] ,int[] arr2 = {1,2,3,4}
<4>索引—访问数组
<5> arr.length
2、重点理解
1).在数组中删除、插入一个数据,为了保证连续性,就需要做大量的数据搬移工作。
2).数组的随机访问效率确实十分的高。时间复杂度为 O(1)。
3).支持动态扩容。使用 ArrayList,每次 存储空间不够的时候,它都会将空间自动扩容为 1.5 倍大小。
3、插入删除
假设数组的长度为 n,将一个数据插入到数组中的第 k 个位置。为了把第 k 个 位置腾出来,给新来的数据,我们需要将第 k~n 这部分的元素都顺序地往后挪一位。
如果在数组的末尾插入元素,那就不需要移动数据了,时间复杂度为 O(1)。
但如果在数组的开头插入元素,那所有的数据都需要依次往后移动一位,所以最坏时间复杂度是 O(n)。 因为我们在 每个位置插入元素的概率是一样的,所以平均情况时间复杂度为 (1+2+…n)/n=O(n)。
删除同理。
2、基于Java中的数组,进行二次封装,制作属于我们自己的数组(可变数组)
package com.company;
import java.util.Random;
public class MySelfArray<T> {
private T[] data;// 数组容器
private int size;// 实际存放元素的个数
private int capacity;// 容积
// 构造函数
public MySelfArray() {
this(100);
}
public MySelfArray(int capacity) {
this.data = (T[]) new Object[capacity];
this.size = 0;
this.capacity = capacity;
}
// 获取数组中实际存放元素的个数
public int getSize() {
return this.size;
}
// 获取容量
public int getCapacity() {
return this.capacity;
}
// 判断数组是否为空
public boolean isEmpty() {
return this.size == 0;
}
// 向数组的尾部添加元素---this.size 永远指向待插入元素的位置
public void addTail(T val) {
this.add(this.size, val);
}
// 向数组的头部添加元素
public void addHead(T val) {
this.add(0, val);
}
// 向任意位置添加元素
public void add(int index, T val) {
if (index < 0 || index > this.size) {
throw new IllegalArgumentException("the index is invalid!");
}
if (this.size == this.data.length) {
// 进行扩容
resize(this.data.length * 2);
}
for (int i = this.size; i > index; i--) {
this.data[i] = this.data[i - 1];
}
this.data[index] = val;
this.size += 1;
}
private void resize(int newCapacity) {
T[] newArr = (T[]) new Object[newCapacity];
// 将源数组中的内容复制到新数组中
for (int i = 0; i < this.size; i++) {
newArr[i] = this.data[i];
}
this.data = newArr;
this.capacity = newCapacity;
}
// 获取指定位置的元素
public T getEleByIndex(int index) {
if (index < 0 || index >= this.size) {
throw new IllegalArgumentException("the index is invalid!");
}
return this.data[index];
}
// 修改指定位置的元素
public void modifyByIndex(int index, T val) {
if (index < 0 || index >= this.size) {
throw new IllegalArgumentException("the index is invalid!");
}
this.data[index] = val;
}
// 判断是否包含打指定的元素
public boolean contains(T val) {
for (int i = 0; i < this.size; i++) {
if (this.data[i].equals(val)) {
return true;
}
}
return false;
}
// 根据val搜索对应的位置
public int search(T val) {
for (int i = 0; i < this.size; i++) {
if (this.data[i].equals(val)) {
return i;
}
}
return -1;
}
// 删除元素
public void removeEle(T val) {
for (int i = 0; i < this.size; i++) {
if (this.data[i].equals(val)) {
for (int j = i; j < this.size - 1; j++) {
this.data[j] = this.data[j + 1];
}
break;
}
}
this.size -= 1;
// 进行缩容
if (this.size == this.capacity / 2 && this.capacity / 2 > 0) {
resize(this.capacity / 2);
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < this.size; i++) {
sb.append(this.data[i]);
if (i != this.size - 1) {
sb.append(",");
}
}
sb.append("]");
return sb.toString();
}
public static void main(String[] args) {
Random random = new Random();
int count = 20;
MySelfArray<Integer> arr = new MySelfArray<>(5);
for (int i = 0; i < count; i++) {
arr.addTail(random.nextInt(30));
System.out.println("容量:" + arr.getCapacity() + "--->" + arr);
System.out.println("--------------分隔线---------------");
}
for (int i = 0; i < 30; i++) {
arr.removeEle(random.nextInt(30));
System.out.println("容量:" + arr.getCapacity() + "--->" + arr);
}
}
}