目录
数组是应用最广泛的数据存储结构。它被植入大部分的编程语音。在Java中数组用来存放一种类型的集合。
1.数组的介绍
①数组的声明
第一种方式:
int[] arr = new int[10];//数组类型[] 数组名称 = new 数组类型 [数组大小];
创建数组并声明数组大小
第二种方式:
int[] arr = new int[]{1,2,3,4};//数组类型[] 数组名称 = new 数组类型[数组元素1,数组元素2.......];
创建数组并直接初始化数组里的元素
②访问数组元素及给数组元素赋值
数组在内存中是连续的数据结构,在运行期间不可变。它有一个下标,从0给数组计数。通过访问下标即可快速的访问和修改数组
//新建一个长度为4数组
int[] arr = new int[]{1,2,3,4};//访问数组的第一个元素
int i = arr[0];//修改数组的第二个元素
arr[1] = i;
③数组的遍历
数组具有一个length属性表示数组长度,通过下标和length可以遍历数组
for (int j = 0; j < arr.length; j++) {
System.out.println(arr[j]);
}
2.类封装
使用类来封装数组,使用户不必了解数组的结构而可以直接通过insert/delete/find/display方法来使用数组
/*** 实现基本的数据结构功能
* 1.查找
* 2.插入
* 3.删除
* 4.迭代*/
public classMyArray {//存储数据的数组
private int[] array;//数组内实际元素个数
private intelems;//数据最大容量
private intlength;publicMyArray(){this.elems = 0;this.length = 50;
array= new int[length];
}public MyArray(intlength){this.elems = 0;this.length =length;
array= new int[length];
}//根据下标查找数据元素
public int get(inti){if(i<0 || i>=elems)System.out.println("数组越界");returnarray[i];
}//在数组末尾插入元素
public void insert(inti){if(elems==length)System.out.println("数组已达到最大容量,需要扩容");
array[elems]=i;
elems++;
}//删除指定元素 true删除成功 false删除失败
public boolean delete(intvalue){int k =find(value);if(k==-1){return false;
}else{for (int i = k; i
array[k]= array[k+1];
}
elems--;
}return true;
}//查询指定元素,返回元素下标,没有找到返回-1
public int find(intvalue){for (int i = 0; i < elems; i++) {if(array[i]==value)returni;
}return -1;
}//遍历数组
public voiddisplay(){for (int i = 0; i
System.out.println(array[i]);
}
}
}
3.扩展(有序数组)
前面我们封装了一个无序数组,无序数组在不知道下标的情况下,通过一个一个的遍历比较来查找元素,时间复杂度为O(n),效率不是很高
我们决定优化下它,首先使数组成为一个有序数组,find方法使用二分查找的方式,不断对半减少查找范围,时间复杂度为O(logn)
查询过程可以参考下图:
//当数组有序的时候,使用二分查找,查询指定元素
public int find(intvalue){int low = 0;int high = elems-1;intcur;while (true){
cur= low + (high-low)/2;if(array[cur]==value){returncur;
}else if(low >high){return -1;
}else if(array[cur]>value){
high= cur -1;
}else{
low= cur +1;
}
}
}
4.数组的局限
上面我们介绍了数组,数组似乎可以完成所有工作,但我们不用它作为所有的数据存储,是因为数组的缺陷。
(1) 数组在知道下标的时候查询效率很高,但不知道下标查询指定元素的时候效率却很低
(2)向指定位置修改和删除数据的时候,数组需要移动数组,来保持数组的连续性。移动数组其实就是重新拷贝一个数组,这个过程比较耗时
(3)创建出的数组大小固定,容量过大会导致浪费,容量过小,数组很容易达到最大容量,导致数组下标越界
为了解决这种情况,我们需要更加灵活的数据结构。