1、定义
数组(Array)是一种线性表数据结构 ,用于 存储 一组具有相同类型的数据元素。 数组是一种有序的集合,通过编号来唯一标识每个元素,即所谓的下标。

2、特性
- 线性表:线性表是一种数据元素顺序排列、类型相同的数据结构,每个元素最多只有前驱和后继两个相邻元素。数组正是线性表的一种典型实现,此外,栈、队列、链表等也属于线性表结构。
- 连续的内存空间:线性表有「顺序存储」和「链式存储」两种方式。顺序存储结构要求内存空间连续,相邻元素在物理内存中紧挨着。数组采用的正是顺序存储结构,且所有元素类型一致。
3、特点
- 类型统一:数组中的所有元素都必须是相同的数据类型。
- 固定大小:一旦创建了数组,其大小就固定不变。
- 连续存储:数组的所有元素在内存中是连续存放的。
- 随机访问:可以直接通过索引访问任意位置的元素,时间复杂度为O(1)。
4、操作方法
数组支持多种基本操作,包括初始化、访问、插入、删除等
4.1 初始化
声明数组
// 静态初始化
int[] arr1 = {1, 2, 3, 4, 5};
String[] arr2 = {"Java", "Python", "C++"};
// 动态初始化
int[] arr3 = new int[5];
arr3[0] = 10;
arr3[1] = 20;
4.2 访问
通过下标索引进行访问
// 2. 访问元素
System.out.println("\n=== 访问操作 ===");
System.out.println("第一个元素: " + arr[0]); // 索引0
System.out.println("最后一个元素: " + arr[arr.length - 1]); // 索引 length-1
4.3 修改
通过下标直接进行修改即可
// 3. 修改元素
System.out.println("\n=== 修改操作 ===");
arr[2] = 100; // 修改第三个元素
System.out.println("修改后: " + Arrays.toString(arr));
4.4 遍历
使用length表示数组的长度
// 4. 遍历数组
System.out.println("\n=== 遍历数组 ===");
System.out.print("for循环: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.print("\n增强for循环: ");
for (int num : arr) {
System.out.print(num + " ");
}
4.5 查找
通过下表进行查找
// 5. 查找元素
System.out.println("\n\n=== 查找操作 ===");
int target = 40;
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
index = i;
break;
}
}
System.out.println(target + " 的索引位置: " + (index != -1 ? index : "未找到"));
4.6 确定数组长度与类型
// 6. 获取数组信息
System.out.println("\n=== 数组信息 ===");
System.out.println("数组长度: " + arr.length);
System.out.println("数组类型: " + arr.getClass().getSimpleName());
5、算法
5.1 插入
public class ArrayInsert {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 0, 0, 0}; // 预留空间
int size = 5; // 当前有效元素个数
System.out.println("插入前: " + Arrays.toString(arr));
// 在索引2处插入100
int insertIndex = 2;
int insertValue = 100;
// 从后往前移动元素
for (int i = size; i > insertIndex; i--) {
arr[i] = arr[i - 1];
}
// 插入新元素
arr[insertIndex] = insertValue;
size++; // 有效元素增加
System.out.println("插入后: " + Arrays.toString(arr));
}
}
5.2 删除
public class ArrayDelete {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
int size = 5;
System.out.println("删除前: " + Arrays.toString(arr));
// 删除索引2处的元素
int deleteIndex = 2;
// 从删除位置开始,向前移动元素
for (int i = deleteIndex; i < size - 1; i++) {
arr[i] = arr[i + 1];
}
// 最后一个元素置0(可选)
arr[size - 1] = 0;
size--; // 有效元素减少
System.out.println("删除后: " + Arrays.toString(Arrays.copyOf(arr, size)));
}
}
5.3 反转数组
public class ArrayReverse {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
System.out.println("反转前: " + Arrays.toString(arr));
// 双指针法反转
int left = 0;
int right = arr.length - 1;
while (left < right) {
// 交换元素
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
System.out.println("反转后: " + Arrays.toString(arr));
}
}
5.4 查找最大最小值
public class ArrayMinMax {
public static void main(String[] args) {
int[] arr = {3, 5, 1, 8, 2, 7};
int min = arr[0];
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
if (arr[i] > max) {
max = arr[i];
}
}
System.out.println("数组: " + Arrays.toString(arr));
System.out.println("最小值: " + min);
System.out.println("最大值: " + max);
}
}
6、二维数组
public class TwoDArray {
public static void main(String[] args) {
// 1. 声明和初始化
int[][] matrix1 = new int[3][4]; // 3行4列
int[][] matrix2 = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 2. 访问元素
System.out.println("matrix2[1][2] = " + matrix2[1][2]); // 6
// 3. 遍历二维数组
System.out.println("\n遍历二维数组:");
for (int i = 0; i < matrix2.length; i++) { // 行
for (int j = 0; j < matrix2[i].length; j++) { // 列
System.out.print(matrix2[i][j] + "\t");
}
System.out.println();
}
// 4. 获取数组信息
System.out.println("\n行数: " + matrix2.length);
System.out.println("列数: " + matrix2[0].length);
}
}
7、矩阵转置
public class MatrixTranspose {
public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3},
{4, 5, 6}
};
System.out.println("原始矩阵:");
printMatrix(matrix);
// 转置
int rows = matrix.length;
int cols = matrix[0].length;
int[][] transpose = new int[cols][rows];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
transpose[j][i] = matrix[i][j];
}
}
System.out.println("转置矩阵:");
printMatrix(transpose);
}
static void printMatrix(int[][] matrix) {
for (int[] row : matrix) {
for (int num : row) {
System.out.print(num + "\t");
}
System.out.println();
}
}
}
8、常用方法
import java.util.Arrays;
public class ArraysUtility {
public static void main(String[] args) {
int[] arr = {5, 3, 8, 1, 9, 2};
// 1. 排序
Arrays.sort(arr);
System.out.println("排序后: " + Arrays.toString(arr));
// 2. 二分查找(必须先排序)
int index = Arrays.binarySearch(arr, 8);
System.out.println("8的索引: " + index);
// 3. 填充数组
int[] arr2 = new int[5];
Arrays.fill(arr2, 7);
System.out.println("填充后: " + Arrays.toString(arr2));
// 4. 复制数组
int[] arr3 = Arrays.copyOf(arr, 3); // 复制前3个
System.out.println("复制前3个: " + Arrays.toString(arr3));
int[] arr4 = Arrays.copyOfRange(arr, 2, 5); // 复制[2,5)
System.out.println("复制[2,5): " + Arrays.toString(arr4));
// 5. 比较数组
int[] a1 = {1, 2, 3};
int[] a2 = {1, 2, 3};
System.out.println("数组相等: " + Arrays.equals(a1, a2));
}
}
9、去重
public class ArrayRemoveDuplicates {
public static void main(String[] args) {
int[] arr = {1, 2, 2, 3, 4, 4, 5, 5, 5};
// 假设数组已排序
Arrays.sort(arr);
int j = 0; // 指向不重复元素的最后一个位置
for (int i = 1; i < arr.length; i++) {
if (arr[i] != arr[j]) {
j++;
arr[j] = arr[i];
}
}
// 截取不重复部分
int[] result = Arrays.copyOf(arr, j + 1);
System.out.println("去重后: " + Arrays.toString(result));
}
}
10、寻找数组中缺失的数字
public class MissingNumber {
public static void main(String[] args) {
int[] arr = {3, 0, 1}; // 缺失2
int n = arr.length;
int expectedSum = n * (n + 1) / 2;
int actualSum = 0;
for (int num : arr) {
actualSum += num;
}
int missing = expectedSum - actualSum;
System.out.println("缺失的数字: " + missing);
}
}
11、合并两个有序数组
public class MergeSortedArrays {
public static void main(String[] args) {
int[] arr1 = {1, 3, 5, 7};
int[] arr2 = {2, 4, 6, 8, 10};
int[] result = new int[arr1.length + arr2.length];
int i = 0, j = 0, k = 0;
// 合并
while (i < arr1.length && j < arr2.length) {
if (arr1[i] < arr2[j]) {
result[k++] = arr1[i++];
} else {
result[k++] = arr2[j++];
}
}
// 处理剩余元素
while (i < arr1.length) {
result[k++] = arr1[i++];
}
while (j < arr2.length) {
result[k++] = arr2[j++];
}
System.out.println("合并后: " + Arrays.toString(result));
}
}
12、数组的优缺点
优点:
-
随机访问快:通过索引直接访问,O(1)时间复杂度
-
内存连续:CPU缓存友好
-
简单易用:基本数据类型,所有语言都支持
缺点:
-
固定大小:创建后不能改变大小
-
插入删除慢:需要移动元素,O(n)时间复杂度
-
内存浪费:必须预留足够空间