一、概念
结构 | 是一种线性表(元素排列成直线的结构),创建数组会开辟一块连续的内存空间,长度固定无法更改,元素可以重复且只能是同一种类型(Object类型数组除外)。 |
优点 | 查询快:由于元素是连续存储的,带有索引查询起来快。 |
缺点 | 增删慢:由于初始化后长度固定无法更改,增删元素只能用一个新的数组去存储。 |
二、一维数组
2.1 初始化
动态初始化 | 指定数组长度,元素由系统分配(值都为null)。 |
格式:数据类型[] 数组名称= new 数据类型[元素个数] | |
静态初始化 | 指定元素,长度由系统分配。 |
数据类型[] 数组名称 = { 元素1, 元素2, 元素3 } |
//动态初始化
int[] arr = new int[5]; //推荐
int arr[] = new int[5];
//静态初始化
int[] arr = { 1, 2, 3 } //推荐
int[] arr = new int[] { 1, 2, 3 }
2.2 获取、赋值
int x = arr[1] //获取元素
arr[2] = 4 //对元素赋值
int len = arr.length //获取数组长度
int[] arr2 = arr //复制数组,只是赋值了引用,并没有创建新数组,对arr中元素的修改会影响arr2
2.3 增删
数组长度不可改变,在处理固定大小数据的时候性能更好,有增删需求推荐使用 ArrayList,否则需要遍历旧数组对元素进行操作后存储到新数组中,或者遍历旧数组对目标元素位置后面的元素索引+1或-1即整体向前或向后移动1位。
2.4 遍历
for(int i = 0; i < arr.length; i++) //for循环
for(int i : arr) //for-each循环
2.5 查找
方式 | 说明 | 优点 | 缺点 |
线性查找 | 从头到尾遍历,返回该值在数组中第一次出现的位置(即便有多个相同的值)。 | 元素无序也能用。 | 数据量大、目标值靠后、目标值不存在,比较次数会增多更耗时。 |
二分查找 | 适用于元素数量较大时,但必须保证元素是有序的(升序或降序)。 | 数据量较大时,每次比较能排除一半的元素。 | 只能用在有序数组中。 |
2.5.1 顺序查找
public int getIndex(int[] arr, int targetValue) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == targetValue) {
return i;
}
}
return -1; //索引不存在负数,以此表达无结果
}
2.5.2 折半查找 / 二分查找
//方式一
public int halfSearch(int[] arr, int targetValue) {
int min = 0; //最小索引
int max = arr.length - 1; //最大索引
int mid = (min + max) / 2 ; //中间值索引
while (arr[mid] != targetValue) {
if (arr[mid] < targetValue) {
min = mid + 1;
} else if (arr[mid] > targetValue) {
max = mid - 1;
}
if (min > max) return -1; //最值交叉无法折半,没有找到
mid = (min + max) / 2;
}
return mid;
}
//方式二
public int halfSearch2(int[] arr, int targetValue) {
int min = 0; //最小索引
int max = arr.length - 1; //最大索引
while(min <= max) {
int mid = (min + max) / 2 ; //中间值索引
if (arr[mid] < targetValue) {
min = mid + 1;
} else if (arr[mid] > targetValue) {
max = mid - 1;
} else {
return mid;
}
}
return -1; //若想把 targetValue 插入还保持数组有序,则 -1 改为 min
}
2.6 排序
实际开发中直接用 Arrays.sort(arr)
2.6.1 选择排序
内循环一次,最值出现在头部索引位置。
public void selectSort(int[] arr) {
//-1是最后一个元素不跟自己比较
for (int i = 0; i < arr.length -1; i++) {
//j+1是避免第一个元素跟自己比较
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) { //改成 < 则是从小到大排序
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
2.6.2 冒泡排序
内循环一次,最值出现在尾部索引位置。有N个元素排序,外循环 N-1 次,内循环 N-i-1 次。
public void bubbleSort(int[] arr) {
//-1是最后一个元素不跟自己比较
for (int i = 0; i < arr.length - 1; i++) {
//j=0是每次从0开始比较,-i是每一轮元素减少1个,-1是避免索引越界
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) { //改成 < 则是从小到大排序
//将两个元素互换位置
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
三、二维数组
(一维)数组中的每个元素也是一个(二维)数组。
3.1 命名格式
//正确写法
int[][] arr1 = new int[3][2];
//以下两种IDE会提示是C语言风格,让写成第一种
int arr2 [][] = new int[3][2];
int[] arr3[] = new int[3][2];
//以下这种IDE也会提示C语言风格,a和b是两个变量,a是一维数组,b是二维数组
int[]x,y[] = new int[3][2];
//会让写成这样
int[]a;
int[][] b = new int[3][2];
3.2 初始化
int[][] arr1 = new int[3][2];
System.out.println(arr1[1]); //打印一维数组元素默认值为内存地址值
System.out.println(arr1[1][1]); //打印二维数组元素默认值为0
int[][] arr2 = new int[3][];
System.out.println(arr2[1]); //打印一维数组元素默认值为null
System.out.println(arr2[1][1]); //打印二维数组元素报错,因为一维元素是null
arr2[0] = new int[2]; //对二维数组元素赋值后,打印一维数组元素默认值为地址值,二维数组元素默认值为0
int[][] arr3 = { {1,2},{3,4},{5,6} }; //打印一维数组元素默认值为地址值
3.3 遍历
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
}
}