目录
一维数组
一维数组实质上是一组相同类型数据的线性集合
1.创建一维数组
1.1先声明,再用new运算符进行内存分配
声明一维数组有以下两种方式
数组元素类型 数组名字【】;
数组元素类型【】 数组名字;
1.2声明的同时为数组分配内存
语法如下
数组元素的类型 数组名 = new 数组元素的类型【数组元素的个数】
2.初始化一维数组
初始化的两种类型
int arr[]= new int[1,2,3,4,5,45] //第一种初始化方式
int arr2[]= {1,2,3,4,5,4} //第二种初始化方式
3.使用一维数组
一维数组是一种基本的数据结构,它可以用来存储一组相同类型的数据。我们可以使用一维数组来解决许多问题,例如:
- 计算数组中的最大值和最小值;
- 对数组进行排序;
- 查找数组中的某个元素;
- 统计数组中某个数出现的次数等等。
下面是一些使用一维数组解决问题的示例代码:
- 计算数组中的最大值和最小值
int[] arr = {1, 3, 5, 2, 4};
int max = arr[0]; // 初始化最大值为数组的第一个元素
int min = arr[0]; // 初始化最小值为数组的第一个元素
for (int i = 1; i < arr.length; i++) { // 遍历数组
if (arr[i] > max) {
max = arr[i]; // 更新最大值
}
if (arr[i] < min) {
min = arr[i]; // 更新最小值
}
}
System.out.println("最大值为:" + max);
System.out.println("最小值为:" + min);
- 对数组进行排序
int[] arr = {1, 3, 5, 2, 4};
for (int i = 0; i < arr.length - 1; i++) { // 外层循环控制排序的趟数
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;
}
}
}
System.out.print("排序后的数组为:");
for (int i = 0; i < arr.length; i++) { // 遍历数组输出
System.out.print(arr[i] + " ");
}
- 查找数组中的某个元素
int[] arr = {1, 3, 5, 2, 4};
int num = 5;
int index = -1; // 初始化查找结果为-1
for (int i = 0; i < arr.length; i++) { // 遍历数组
if (arr[i] == num) { // 如果找到了该元素
index = i; // 更新查找结果
break; // 结束循环
}
}
if (index != -1) { // 如果找到了该元素
System.out.println("元素" + num + "的下标为:" + index);
} else { // 如果没有找到该元素
System.out.println("元素" + num + "不存在!");
}
- 统计数组中某个数出现的次数
int[] arr = {1, 3, 5, 2, 4, 5, 2, 5};
int num = 5;
int count = 0; // 初始化出现次数为0
for (int i = 0; i < arr.length; i++) { // 遍历数组
if (arr[i] == num) { // 如果找到了该元素
count++; // 更新出现次数
}
}
System.out.println("元素" + num + "出现的次数为:" + count);
二维数组
1.二维数组的创建
二维数组可以看成特殊的一维数组
二维数组的创建有两种方式
1.1先声明,再用new运算符进行内存分配
声明二维数组的语句如下
数组元素的类型 数组名字【】【】;
数组元素的类型【】【】 数组名字;
2.声明的同时为数组分配内存
在Java中,可以使用以下语法同时声明数组并为其分配内存:
<数据类型>[] <数组名称> = new <数据类型>[<数组长度>];
其中,
<数据类型>
:数组中元素的数据类型,可以是任意的基本类型或引用类型;<数组名称>
:数组的名称,可以使用任意有效的标识符命名;<数组长度>
:数组的长度,即数组中元素的个数,应为一个正整数。
例如,声明一个长度为5的整型数组,可以使用以下语句:
int[] arr = new int[5];
这里,我们同时声明了一个整型数组arr
并分配了长度为5的内存空间。注意,如果数组中的元素是引用类型,例如String
、Object
等,则需要使用相应的引用类型进行声明。
可以通过以下代码验证数组长度:
int[] arr = new int[5];
System.out.println("数组长度为:" + arr.length); // 输出:数组长度为:5
这里,我们使用数组的length
属性获取其长度,并输出到控制台。
2.二维数组初始化
语法如下
type arrayname[][]={value1,value2,value3.....};
3.使用二维数组
在Java中,可以使用二维数组来存储具有多个维度的数据。二维数组本质上是由多个一维数组组成的。
声明二维数组的语法如下:
<数据类型>[][] <数组名称> = new <数据类型>[<行数>][<列数>];
其中,
<数据类型>
:数组中元素的数据类型,可以是任意的基本类型或引用类型;<数组名称>
:数组的名称,可以使用任意有效的标识符命名;<行数>
:数组的行数,即数组中第一维元素的个数,应为一个正整数;<列数>
:数组的列数,即数组中第二维元素的个数,应为一个正整数。
例如,声明一个3行4列的二维整型数组,可以使用以下语句:
int[][] arr = new int[3][4];
这里,我们声明了一个二维整型数组arr
,其行数为3,列数为4。可以通过以下代码验证数组的行列数:
int[][] arr = new int[3][4];
System.out.println("数组行数为:" + arr.length); // 输出:数组行数为:3
System.out.println("数组列数为:" + arr[0].length); // 输出:数组列数为:4
这里,我们使用数组的length
属性获取其行数,使用arr[0].length
获取其列数,并输出到控制台。
使用二维数组时,可以使用两层循环来遍历其所有元素,例如:
int[][] arr = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
这里,我们使用了一个已经声明并初始化的二维数组arr
,并使用两层循环依次输出其所有元素。输出结果为:
1 2 3
4 5 6
7 8 9
数组的基本操作
1.遍历数组
在Java中,有多种方式可以遍历数组。下面介绍三种常用的遍历方式:
- 使用for循环遍历一维数组
可以使用for循环遍历一维数组。遍历过程中,使用循环变量控制数组下标,逐一访问数组元素。
示例代码:
int[] arr = {1, 2, 3, 4, 5};
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
输出结果:1 2 3 4 5
- 使用foreach遍历一维数组
可以使用foreach循环简化一维数组的遍历过程,不需要使用下标进行访问,foreach循环会将数组中的每个元素依次赋值给循环变量。
示例代码:
int[] arr = {1, 2, 3, 4, 5};
for (int num : arr) {
System.out.print(num + " ");
}
输出结果:1 2 3 4 5
- 使用双层for循环遍历二维数组
可以使用两层for循环遍历二维数组。外层循环控制行数,内层循环控制列数,逐一访问数组元素。
示例代码:
int[][] arr = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println(); // 换行
}
输出结果:
1 2 3
4 5 6
7 8 9
以上是三种常用的遍历数组的方法。根据实际情况,选择合适的方法可以提高代码效率和可读性。
2.填充替换数组元素
数组元素定义完成后,可通过Arrays类的静态方法fill()来对数组中的元素进行替换。该方法通过各种重载形式可完成对任意类型的数组元素的替换。fill()方法有两种参数类型,下面以ing型数组为例介绍fill()方法的使用方法。
(1)fill(int[] a,int value)
该方法可将指定的int值分配给int型数组的每个元素
语法如下:
fill(int[] a,int value)
(2)fill(int[] a,int fromIndex,int toIndex,int value)
该方法将指定的int值分配给int型数组指定范围中的每个元素。
fill(int[] a,int fromIndex,int toIndex ,int value)
3.对数组进行排序
在Java中,可以使用Arrays类提供的sort方法来对数组进行排序。
- 对一维数组进行排序
可以使用Arrays工具类提供的sort
方法来对一维数组进行排序。该方法默认按从小到大的顺序进行排序。
示例代码:
int[] arr = {5, 2, 4, 1, 3};
Arrays.sort(arr); // 对数组进行排序
System.out.println(Arrays.toString(arr)); // 输出:[1, 2, 3, 4, 5]
如果需要按从大到小的顺序进行排序,可以使用Arrays工具类提供的sort
方法的另一个重载方法,传入自定义的Comparator对象来实现排序。
示例代码:
Integer[] arr = {5, 2, 4, 1, 3};
Arrays.sort(arr, Collections.reverseOrder()); // 对数组进行排序
System.out.println(Arrays.toString(arr)); // 输出:[5, 4, 3, 2, 1]
- 对二维数组进行排序
可以使用Arrays工具类提供的sort
方法,结合Comparator对象来对二维数组的每一行进行排序。
示例代码:
int[][] arr = {{5, 2}, {1, 3}, {4, 6}};
Arrays.sort(arr, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
}); // 对每一行按第一列进行排序
System.out.println(Arrays.deepToString(arr)); // 输出:[[1, 3], [4, 6], [5, 2]]
该示例代码中,我们定义了一个匿名的Comparator对象,对每一行按第一列进行排序,并使用Arrays工具类提供的sort方法进行排序。
注意:二维数组排序时,只能排序每一行的元素,不能对整个二维数组进行排序。如果需要对整个二维数组进行排序,可以将二维数组转换为一维数组后进行排序。
4.复制数组
在Java中,可以使用Arrays类提供的copyOf方法来复制数组。该方法可以复制指定长度的数组,如果目标长度比原数组的长度小,则只会复制前面的元素,后面的元素会被赋默认值。
示例代码:
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = Arrays.copyOf(arr1, arr1.length); // 复制整个数组
System.out.println(Arrays.toString(arr2)); // 输出:[1, 2, 3, 4, 5]
int[] arr3 = Arrays.copyOf(arr1, 3); // 复制前三个元素
System.out.println(Arrays.toString(arr3)); // 输出:[1, 2, 3]
int[] arr4 = Arrays.copyOf(arr1, 7); // 复制前七个元素
System.out.println(Arrays.toString(arr4)); // 输出:[1, 2, 3, 4, 5, 0, 0]
除了copyOf方法外,还可以使用System类提供的arraycopy方法来复制数组。该方法可以复制指定范围内的数组元素,并可以指定复制后的起始位置。
示例代码:
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = new int[3];
System.arraycopy(arr1, 0, arr2, 0, 3); // 复制前三个元素到arr2数组中
System.out.println(Arrays.toString(arr2)); // 输出:[1, 2, 3]
在该示例代码中,我们使用System类的arraycopy方法,复制arr1数组中前三个元素到arr2数组中,并从arr2数组的起始位置开始填充。
5.数组查询
在Java中,可以使用Arrays类提供的一系列方法来查询数组,如查找指定元素在数组中的位置、查找数组中的最大值和最小值等。
以下是常用的数组查询方法:
- binarySearch:用来在已排序的数组中查找指定元素的位置。如果找到该元素,则返回该元素在数组中的索引;如果找不到,则返回一个负数,表示应该插入该元素以保持数组的有序性。
示例代码:
int[] arr = {1, 3, 5, 7, 9};
int index = Arrays.binarySearch(arr, 5); // 查找5在数组中的位置
System.out.println(index); // 输出:2
- sort:用来对数组进行排序,可以按升序或降序排列。
示例代码:
int[] arr = {5, 3, 9, 1, 7};
Arrays.sort(arr); // 将数组按升序排序
System.out.println(Arrays.toString(arr)); // 输出:[1, 3, 5, 7, 9]
- fill:用来将数组中的所有元素都赋成指定的值。
示例代码:
int[] arr = new int[5];
Arrays.fill(arr, 1); // 将数组所有元素都赋值为1
System.out.println(Arrays.toString(arr)); // 输出:[1, 1, 1, 1, 1]
- toString:用来将数组转换成字符串,方便输出。
示例代码:
int[] arr = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(arr)); // 输出:[1, 2, 3, 4, 5]
- equals:用来比较两个数组是否相等,即数组中的元素类型和个数都相同,并且相同索引处的元素值也相等。
示例代码:
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
System.out.println(Arrays.equals(arr1, arr2)); // 输出:true
int[] arr3 = {1, 2, 4};
System.out.println(Arrays.equals(arr1, arr3)); // 输出:false
上述方法都是通过Arrays类提供的静态方法实现的。使用这些方法可以方便地对数组进行查询和操作。
数组的排列算法
1.冒泡排序
冒泡排序是一种简单的排序算法,它重复地遍历要排序的数组,一次比较两个元素,如果它们的顺序错误就交换它们的位置,直到没有需要交换的元素为止。因为每一轮遍历都会将一个元素放到它最终的位置上,所以需要进行 n-1 轮遍历,其中 n 是数组的长度。
以下是冒泡排序的Java实现:
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
// 交换arr[j]和arr[j+1]
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
在上述实现中,外层循环控制遍历轮数,内层循环控制每轮遍历的比较次数。如果当前位置上的元素比下一个位置上的元素大,则交换这两个元素的位置。
时间复杂度为 O(n^2),空间复杂度为 O(1)。虽然它的时间复杂度较高,但是对于小规模的数据排序,冒泡排序仍然是一种简单而有效的排序算法。
2.直接选择排序
直接选择排序是一种简单的排序算法,它重复地从未排序的部分选择最小的元素,将其放到已排序的部分末尾。因为每一次选择都是从未排序的部分中选择最小的,所以需要进行 n-1 次选择,其中 n 是数组的长度。
以下是直接选择排序的Java实现:
public static void selectionSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n-1; i++) {
int minIdx = i;
for (int j = i+1; j < n; j++) {
if (arr[j] < arr[minIdx]) {
minIdx = j;
}
}
if (minIdx != i) {
// 交换arr[i]和arr[minIdx]
int temp = arr[i];
arr[i] = arr[minIdx];
arr[minIdx] = temp;
}
}
}
在上述实现中,外层循环控制选择的轮数,内层循环控制每轮选择的比较次数。我们用一个变量 minIdx 记录当前未排序部分中最小元素的下标,每次比较找到更小的元素时,更新 minIdx 的值。最后,如果 minIdx 和 i 不相等,则交换它们的位置。
时间复杂度为 O(n^2),空间复杂度为 O(1)。虽然它的时间复杂度较高,但是对于小规模的数据排序,直接选择排序仍然是一种简单而有效的排序算法。
3.反转排序
如果要反转一个数组的顺序,可以采用双指针的方法。定义指针left指向数组的首位,指针right指向数组的末位,然后将left指向的元素与right指向的元素进行交换,然后left指针后移,right指针前移,重复这个操作直到left指针大于或等于right指针。
以下是Java代码实现:
public static void reverse(int[] arr) {
int n = arr.length;
int left = 0, right = n-1;
while (left < right) {
// 交换arr[left]和arr[right]
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
// 移动指针
left++;
right--;
}
}
时间复杂度为 O(n),空间复杂度为 O(1)。该算法既简单又高效,可用于对数组进行反转排序。