Java数据结构与算法(一)--数组
目录
数组是应用最广泛的数据存储结构。它被植入大部分的编程语音。在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 class MyArray { //存储数据的数组 private int[] array; //数组内实际元素个数 private int elems; //数据最大容量 private int length; public MyArray(){ this.elems = 0; this.length = 50; array = new int[length]; } public MyArray(int length){ this.elems = 0; this.length = length; array = new int[length]; } //根据下标查找数据元素 public int get(int i){ if(i<0 || i>=elems)System.out.println("数组越界"); return array[i]; } //在数组末尾插入元素 public void insert(int i){ if(elems==length)System.out.println("数组已达到最大容量,需要扩容"); array[elems] = i; elems++; } //删除指定元素 true删除成功 false删除失败 public boolean delete(int value){ int k = find(value); if(k==-1){ return false; }else{ for (int i = k; i <elems-1 ; i++) { array[k] = array[k+1]; } elems--; } return true; } //查询指定元素,返回元素下标,没有找到返回-1 public int find(int value){ for (int i = 0; i < elems; i++) { if(array[i]==value)return i; } return -1; } //遍历数组 public void display(){ for (int i = 0; i <elems ; i++) { System.out.println(array[i]); } } }
3.扩展(有序数组)
前面我们封装了一个无序数组,无序数组在不知道下标的情况下,通过一个一个的遍历比较来查找元素,时间复杂度为O(n),效率不是很高
我们决定优化下它,首先使数组成为一个有序数组,find方法使用二分查找的方式,不断对半减少查找范围,时间复杂度为O(logn)
查询过程可以参考下图:

//当数组有序的时候,使用二分查找,查询指定元素 public int find(int value){ int low = 0; int high = elems-1; int cur; while (true){ cur = low + (high-low)/2; if(array[cur]== value){ return cur; }else if(low > high){ return -1; }else if(array[cur]>value){ high = cur -1; }else{ low = cur +1; } } }
4.数组的局限
上面我们介绍了数组,数组似乎可以完成所有工作,但我们不用它作为所有的数据存储,是因为数组的缺陷。
(1) 数组在知道下标的时候查询效率很高,但不知道下标查询指定元素的时候效率却很低
(2)向指定位置修改和删除数据的时候,数组需要移动数组,来保持数组的连续性。移动数组其实就是重新拷贝一个数组,这个过程比较耗时
(3)创建出的数组大小固定,容量过大会导致浪费,容量过小,数组很容易达到最大容量,导致数组下标越界
为了解决这种情况,我们需要更加灵活的数据结构。

浙公网安备 33010602011771号