Java--day06--数组
一.数组的高级应用
1.数组反转
含义:将数组中的元素按照索引顺序依次进行位置上的互换
反转的前提条件:
1.确认待交换元素的索引位置
int start = 0;
int end = arr.length - 1
2.每次交换后索引位置移动的规律
start++
end–
3.如何交换两个索引位置上元素
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
4.满足什么样的条件进行两个索引位置上元素的交换:
当数组的长度为奇数个时:start < end
当数组的长度为偶数个时:start < end
代码如下:
//声明并初始化数组
int[] arr = {11,22,33,44,55};
System.out.print("反转前:[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
System.out.println(arr[i] + "]");
} else {
System.out.print(arr[i] + ", ");
}
}
//进行数组的反转操作
for (int start = 0 , end = arr.length - 1 ; start < end ; start++ , end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
System.out.print("反转后:[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
System.out.println(arr[i] + "]");
} else {
System.out.print(arr[i] + ", ");
}
}
2.冒泡排序
冒泡排序:其实就是求最大值排序
原理:比较两个相邻的元素,将两个元素中较大的元素交换到右侧
分析:
1.考虑遍历一次无法将数组中元素进行排序好,所有进行多次遍历,选择循环嵌套格式
2.外层循环的循环变量控制的是"求几次最大值"
3. 内层循环的循环变量控制的是"求一次最大值需要进行几次排序"
代码如下:
//声明并初始化数组
int[] arr = {5,4,6,8,9};
//进行数组的排序
/*
当进行第1轮遍历时:需要进行5-1次判断;
当进行第2轮遍历时:需要进行5-2次判断;
当进行第3轮遍历时:需要进行5-3次判断;
当进行第4轮遍历时:需要进行5-4次判断;
*/
//外层循环:求几次最大值
//核心代码
for (int i = 1; i < arr.length ; i++) {
//内层循环:求一次最大值需要多少次判断
for (int j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
3.选择排序
原理:每一趟从待排序的数据中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕 。
思路:给定数组:int[ ] arr={里面n个数据};第一趟排序,在待排序数据1~n中选出最小的数据,将
它与数据1交换;第二趟,在待排序数据2~n中选出最小的数据,将它与数据2交换;以此类推,第i
趟在待排序数据数据i~n中选出最小的数据,将它与数据i交换,直到全部排序完成。
代码如下(核心代码):
int[] arr = {5,4,6,8,9};
for (int i = 0; i < arr.length - 1 ; i++ ) {
// 记录当前趟数临时最小值的索引
int index = i;
// 遍历数组,拿到临时最小值的索引
for (int j = i + 1 ; j < arr.length; j++ ) {
if (arr[index] > arr[j]) {
index = j;
}
}
// 如果临时最小值的索引位置变动,进行位置的交换
if (index != i) {
int temp = arr[index];
arr[index] = arr[i];
arr[i] = temp;
}
}
4.数组的二分查找法
二分查找:对折对折再对折
要求:要求数组元素必须支持比较大小,并且数组中的元素已经按大小排好序
代码如下(核心代码):
int[] arr = {2,5,7,8,10,15,18,20,22,25,28};//数组是有序的
int value = 18;
int index = -1;
int start = 0;
int end = arr.length - 1;
int mid = (start + end)/2;
while(start <= end){
if(value > arr[mid]) {
//移动左边界,使得mid往右移动
start = mid + 1;
} else if(value < arr[mid]){//往左边继续查找
end = mid - 1;
} else {
index = mid;
break;
}
mid = (start + end)/2;
}
if(index==-1){
System.out.println(value + "不存在");
}else{
System.out.println(value + "的下标是" + index);
}
二.数组和方法的综合应用
1.可变参数
在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化成如下格式:
修饰符 返回值类型 方法名(参数类型... 形参名){ }
其实这个书写完全等价于
修饰符 返回值类型 方法名(参数类型[] 形参名){ }
只是后面这种定义,在调用时必须传递数组,而前者可以直接传递数据即可。
代码如下:
public class Demo {
public static void main(String[] args) {
int[] arr = { 1, 4, 62, 431, 2 };
int sum = getSum(arr);
System.out.println(sum);
// 6 7 2 12 2121
// 求 这几个元素和 6 7 2 12 2121
int sum2 = getSum(6, 7, 2, 12, 2121);
System.out.println(sum2);
}
/*
* 完成数组 所有元素的求和 原始写法
public int getSum(int[] arr){
int sum = 0;
for (int i = 0 ; i < arr.length ; i++) {
sum += arr[i];
}
return sum;
}
*/
//可变参数写法
public static int getSum(int... arr) {
int sum = 0;
for (int i = 0 ; i < arr.length ; i++) {
sum += arr[i];
}
return sum;
}
}
可变参数的注意事项:
1.当声明一个方法时,方法的形参列表除了可变参数外还存在其它参数,需要将可变参数声明在形参列表中的最后位置,否则编译报错
2.当声明一个方法时,方法的形参列表中最多只能含有一个可变参数,否则编译报错
2.方法形式参数和实际参数的特点
形参:在定义方法时方法名后面括号中的变量名称称为形式参数(简称形参),即形参出现在方法
定义中。
实参:调用者方法中调用另一个方法时,方法名后面括号中的参数称为实际参数(简称实参),即实参出现在调用者方法中。
形式参数和实际参数的特点:
方法的形参是基本数据类型时,形参值的改变不会影响实参;
方法的形参是引用数据类型时,形参地址值的改变不会影响实参,但是形参地址值里面的数据的改变会影响实参。
3.数组的动态扩容,删除,插入
(此内容我单拿出来讲)
三. 二维数组
二维数组: 数组中的元素依然是数组
二维数组的声明:
数据类型[][] 数组名;(推荐)
数据类型 数组名[][];
数据类型[] 数组名[];
1.二维数组的初始化
动态初始化
格式1:初始化二维数组的同时,初始化里面每个一维数组
数据类型[][] 数组名 = new 数据类型[x][y];
x : 二维数组中含有多少个一维数组
y : 每个一维数组中含有多少个元素
格式2:初始化二维数组但不会初始化里面每个一维数组
数据类型[][] 数组名 = new 数据类型[x][];
静态初始化
格式1:
数据类型[][] 数组名 = new 数据类型[][]{new 数据类型[]{元素1,元素2,...,元素n},new 数据类型[]{元素1,元素2,...,元素n},..,new 数据类型[]{元素1,元素2,...,元素n}}
格式2:
数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2,...,元素n},{元素1,元素2,...,元素n},...,{元素1,元素2,...,元素n}}
格式3:
数据类型[][] 数组名 = {{元素1,元素2,...,元素n},{元素1,元素2,..,元素n},...,{元素1,元素2,...,元素n}}
2.二维数组元素的访问:索引
格式:
数组名[x][y]
x:访问元素所在一维数组在二维数组中的索引是多少
y:访问元素在一维数组中索引是多少