数组
一、数组基础
1、数组:把数据码成一排进行存放
最大的优点:快速查询
数组最好应用于“索引有语义”的情况,可以方便查询或修改。但不绝对。
2、二次封装数组
需要实现:增、删、改、查
(1)向数组添加元素
向末尾添加元素
public void addLast(int e) {
if(size==data.length)
throw new IllegalArgumentException("AddLast failed");
data[size]=e;
size++;
}
向指定位置添加元素
public void add(int index,int e) {
if(size==data.length)
throw new IllegalArgumentException("Add failed");
if(index<0||index>size) {
throw new IllegalArgumentException("Add failed.Required rational index");
}
for(int i=size-1;i>=index;i--) {
data[i+1]=data[i];
}
data[index]=e;
size++;
}
public void addLast(int e){
add(size,e)
}
(2)查询和修改
查询:get方法
int get(int index) {
if(index<0 || index>=size)
throw new IllegalArgumentException("failed");
return data[index];
}
修改:set方法
void set(int index,int e) {
if(index<0 || index>=size)
throw new IllegalArgumentException("Index is illegal");
data[index]=e;
}
(3)包含、搜索和删除
包含:
public boolean contains(int e) {
for(int i=0;i<size;i++) {
if(data[i]==e) {
return true;//or return i(返回索引)
}
}
return false;
}
删除:删除元素之后元素向左移
public int remove(int index) {
//判断index合法性
int ret=data[index];
for(int i=index+1;i<size;i++) {
data[i-1]=data[i];
}
size--;
return ret;
}
public void removeElement(int e) {
int index=find(e);
if(index!=-1) {
remove(index);
}
}
3、使用泛型
泛型:让我们的数据结构可以放置“任何”数据类型。不可以是基本数据类型,只能是类对象。每个基本数据类型都有对应的包装类。
public class Array<E>{}
//改动:将参数类型、返回值类型改为E。==改为euqals
测试:Array<Integer> arr=new Array<>(20);
4、动态数组
public void add(int index,E e) {
if(index<0||index>size) {
throw new IllegalArgumentException("Add failed.Required rational index");
}
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++;
}
private void resize(int newCapacity) {
E[] newData=(E[])new Object[newCapacity];
for(int i=0;i<size;i++) {
newData[i]=data[i];
}
data=newData;
}
二、时间复杂度分析
添加:
addLast(e)—O(1);
addFirst(e)—O(n)
add(index,e)—O(n/2)=O(n)
删除:
removeLast(e)—O(1)
removeFirst(e)—O(n)
remove(index,e)—O(n/2)=O(n)
修改:set(index,e)—O(1)
查找:
get(index)—O(1)
contains(e)—O(n)
find(e)—O(n)
resize
均摊复杂度:
假设capacity=n,n+1次addLast,触发resize,总共进行2n+1次基本操作。平均每次addLast操作,进行2次基本操作。
复杂度震荡:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9CuNEzIv-1612155808167)(image/image-20201011174233553.png)]
出现问题的原因:removeLast时resize过于着急(Eager)
解决方案:Lazy。当size==capacity/4时,才将capacity减半。
if(size==data.length/4 && data.length/2!=0){
resize(newCapacity:data.length/2);
}
出现问题的原因:removeLast时resize过于着急(Eager)
解决方案:Lazy。当size==capacity/4时,才将capacity减半。
if(size==data.length/4 && data.length/2!=0){
resize(newCapacity:data.length/2);
}