数组
1.数组的概念
概念:一组
连续的存储空间,存储多个相同数据类型的值,长度是固定的
2.数组的定义方式
先声明、再分配空间: 数据类型[] 数组名; 数组名 = new 数据类型[长度];
声明并分配空间: 数据类型[] 数组名 = new 数据类型[长度];
声明并赋值(繁): 数据类型[] 数组名 = new 数据类型[]{value1,value2,value3,...};
声明并赋值(简): 数据类型[] 数组名 = {value1,value2,value3,...};
/**
* @author WHD
* @description TODO
* @date 2024/1/3 14:10
* 数组的4种声明方式
*/
public class TestArrayDefine {
public static void main(String[] args) {
// 方式1 先声明 再开辟空间
int [] arr1;
arr1 = new int[3];
// 方式2 声明并且分配空间
int [] arr2 = new int[5];
// 方式3 声明并且赋值 繁琐 (注意,这种方式中括号中不能写数组长度)
int [] arr3 = new int[]{55,663,789,456,11,22};
// 方式4 声明并且赋值 简单
int [] arr4 = {11,22,55,77,88};
}
}
3.数组的使用
数组的使用
元素:数组中的每一个数据,称之为元素 element
下标:也叫角标,索引,英文名称index,是自动生成的,从0开始,后续依次加1,用于访问数组中的元素
元素的访问:对数组中的数据赋值以及取值的操作,称之为元素的访问
访问格式:
赋值 数组名[下标] = 值;
取值 System.out.println(数组名[下标]);
不能访问不存在的下标,否则会出现数组下标越界异常:
ArrayIndexOutOfBoundsException
/**
* @author WHD
* @description TODO
* @date 2024/1/3 14:19
* 数组的使用
*
* 元素:数组中的每一个数据,称之为元素 element
* 下标:也叫角标,索引,英文名称index,是自动生成的,从0开始,后续依次加1,用于访问数组中的元素
* 元素的访问:对数组中的数据赋值以及取值的操作,称之为元素的访问
* 访问格式:
* 赋值 数组名[下标] = 值;
* 取值 System.out.println(数组名[下标]);
*
*
* 不能访问不存在的下标,否则会出现数组下标越界异常:ArrayIndexOutOfBoundsException
*/
public class TestArrayUse {
public static void main(String[] args) {
int [] arr1 = new int[5];
// 赋值
arr1[0] = 11;
arr1[1] = 88;
arr1[2] = 78;
arr1[3] = 66;
arr1[4] = 77;
// arr1[15] = 678;
// 取值
System.out.println("第1个元素的值为:" + arr1[0]);
System.out.println("第2个元素的值为:" + arr1[1]);
System.out.println("第3个元素的值为:" + arr1[2]);
System.out.println("第4个元素的值为:" + arr1[3]);
System.out.println("第5个元素的值为:" + arr1[4]);
// System.out.println("第6个元素的值为:" + arr1[5]);
}
}
4. 数组的遍历
数组的遍历
遍历:逐一对数组中的元素进行访问 这个操作称之为数组遍历
import java.util.Scanner;
/**
* @author WHD
* @description TODO
* @date 2024/1/3 14:29
* 数组的遍历
* 遍历:逐一对数组中的元素进行访问 这个操作称之为数组遍历
*/
public class TestArrayForeach {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int [] nums = new int[5];
// 通过循环的方式给数组中的元素赋值
for(int i = 0;i < 5;i++){
System.out.println("请输入数组中的第" + (i + 1) + "个元素的值");
nums[i] = input.nextInt();
}
// 通过循环的方式将数组中的元素都取出来
for(int i = 0;i < 5;i++){
System.out.println("第" + (i + 1) + "个元素的值为:" + nums[i]);
}
}
}
5.数组的属性
数组的属性:length 表示数组的长度 是一个int类型的整数
使用方式:数组名.length
使用length属性好处:阅读性更强 不会出现下标错误的问题
/**
* @author WHD
* @description TODO
* @date 2024/1/3 14:35
* 数组的属性:length 表示数组的长度 是一个int类型的整数
* 使用方式:数组名.length
* 使用length属性好处:阅读性更强 不会出现下标错误的问题
*/
public class TestArrayField {
public static void main(String[] args) {
int [] nums = new int[]{56,1,2,4,7,8};
System.out.println(nums.length);
for(int i = 0;i < nums.length;i++){
System.out.println(nums[i]);
}
}
}
6.数组的默认值
数组的默认值:数组中的元素是有默认值的 开辟完空间以后 默认值即存在
/**
* @author WHD
* @description TODO
* @date 2024/1/3 15:08
* 数组的默认值:数组中的元素是有默认值的 开辟完空间以后 默认值即存在
*/
public class TestArrayDefaultValue {
public static void main(String[] args) {
byte [] arr1 = new byte[3];
for(int i = 0;i < arr1.length;i++){
System.out.print(arr1[i] + "\t");
}
System.out.println();
System.out.println(arr1);
System.out.println("--------------------------------------");
short [] arr2 = new short[4];
System.out.println(arr2);
for(int i = 0;i < arr2.length;i++){
System.out.print(arr2[i] + "\t");
}
System.out.println();
System.out.println("--------------------------------------");
int [] arr3 = new int[5];
System.out.println(arr3);
for(int i = 0;i < arr3.length;i++){
System.out.print(arr3[i] + "\t");
}
System.out.println();
System.out.println("--------------------------------------");
long [] arr4 = new long[6];
System.out.println(arr4);
for(int i = 0;i < arr4.length;i++){
System.out.print(arr4[i] + "\t");
}
System.out.println();
System.out.println("--------------------------------------");
float [] arr5 = new float[2];
for (int i = 0; i < arr5.length; i++) {
System.out.print(arr5[i] + "\t");
}
System.out.println();
System.out.println("--------------------------------------");
double [] arr6 = new double[3];
for (int i = 0; i < arr6.length; i++) {
System.out.print(arr6[i] + "\t");
}
System.out.println();
System.out.println("--------------------------------------");
char [] arr7 = new char[4];
for (int i = 0; i < arr7.length; i++) {
System.out.print(arr7[i] + "\t");
}
System.out.println();
System.out.println("--------------------------------------");
boolean [] arr8 = new boolean[5];
for (int i = 0; i < arr8.length; i++) {
System.out.print(arr8[i] + "\t");
}
System.out.println();
System.out.println("--------------------------------------");
String [] arr9 = new String[3];
for (int i = 0; i < arr9.length; i++) {
System.out.print(arr9[i] + "\t");
}
System.out.println();
}
}
7. 数组的扩容
数组的扩容
1.创建大于原数组长度的新数组。
2.将原数组中的元素依次复制到新数组中。
3.将新数组的地址赋值给原数组。
数组作为引用数据类型 其数组名中保存的是指向堆中的地址 将一个数组 直接 赋值给另外一个数组 赋值是地址
/**
* @author WHD
* @description TODO
* @date 2024/1/3 15:19
* 数组的扩容
* 1.创建大于原数组长度的新数组。
* 2.将原数组中的元素依次复制到新数组中。
* 3.将新数组的地址赋值给原数组。
*/
public class TestArrayGrow {
public static void main(String[] args) {
int [] oldArr = {1,2,3,4,5};
int [] newArr = new int[oldArr.length * 2];
for(int i = 0;i < oldArr.length;i++){
newArr[i] = oldArr[i];
}
System.out.println("---------------------------------------------");
for(int i = 0;i < newArr.length;i++){
System.out.println(newArr[i]);
}
System.out.println("oldArr内存地址:" + oldArr);
System.out.println("newArr内存地址:" + newArr);
// 数组作为引用数据类型 其数组名中保存的是指向堆中的地址
// 将一个数组 直接 赋值给另外一个数组 赋值是地址
oldArr = newArr;
System.out.println("地址赋值以后");
System.out.println("oldArr内存地址:" + oldArr);
System.out.println("newArr内存地址:" + newArr);
System.out.println("oldArr数组长度:" + oldArr.length);
System.out.println("newArr数组长度:" + newArr.length);
}
}
8.复制数组的方式
数组的复制
1.自己编写循环实现元素复制
2.使用System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度);
3.使用java.util.Arrays.copyOf(原数组, 新长度);//返回带有原值的新数组。
import java.util.Arrays;
/**
* @author WHD
* @description TODO
* @date 2024/1/3 15:41
* 数组的复制
* 1.自己编写循环实现元素复制
* 2.使用System.arraycopy(原数组,原数组起始,新数组,新数组起始,长度);
* 3.使用java.util.Arrays.copyOf(原数组, 新长度);//返回带有原值的新数组。
*/
public class TestArrayCopy {
public static void main(String[] args) {
int [] nums1 = {1,2,3,4,5};
int [] nums2 = new int[10];
System.arraycopy(nums1, 1, nums2, 5,4);
for (int i = 0; i < nums2.length; i++) {
System.out.print(nums2[i] + "\t");
}
System.out.println();
System.out.println("-----------------------------------------");
int [] nums = {11,22,33,44,55};
int [] arr = Arrays.copyOf(nums, 10);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
9. 课堂练习
数组的练习:统计int类型数组中所有元素的总和 以及 平均值
/**
* @author WHD
* @description TODO
* @date 2024/1/3 15:50
* 数组的练习:统计int类型数组中所有元素的总和 以及 平均值
*/
public class TestArrayExercise1 {
public static void main(String[] args) {
int [] arr1 = {11,22,33,44,55,66};
// 定义变量 用于统计总和
int sum = 0;
// 遍历数组
for (int i = 0; i < arr1.length; i++) {
sum += arr1[i]; // 将数组中的每个元素 进行累计
}
System.out.println("数组总和为:" + sum); // 打印总和
System.out.println("数组平均值为:" + sum / arr1.length); // 打印平均值
}
}
求一个数组中的最大值,或者最小值。
分析:先假设一个
最大值,将其依次与其他元素比较,遇到更到的元素,则交换头衔,直到比较完毕。
/**
* @author WHD
* @description TODO
* @date 2024/1/3 15:52
* 求一个数组中的最大值,或者最小值。
*
* 分析:先假设一个`最大值`,将其依次与其他元素比较,遇到更到的元素,则交换`头衔`,直到比较完毕。
*/
public class TestArrayExercise2 {
public static void main(String[] args) {
int [] nums = {89,562,741,11,666,999,521,321,20};
// 假设第一个为最大元素
int max = nums[0];
// 假设第一个为最小元素
int min = nums[0];
// 遍历数组
for(int i = 1;i < nums.length;i++){
// 判断元素大小 如果遇到更大的
if(max < nums[i]){
max = nums[i]; // 则交换最大元素的头衔
}
// 如果遇到更小的
if(min > nums[i]){
min = nums[i]; // 则交换最小元素的头衔
}
}
// 打印最大 最小值
System.out.println("最大的元素为:" + max);
System.out.println("最小的元素为:" + min);
}
}
10.数组类型的参数和返回值
数组作为参数,作为返回值使用,使用方式和之前一致。
数组类型的参数和返回值
需求:
1.编写方法实现统计一个学生的5门成绩 并且返回
2.编写方法实现接收用户输入的5门成绩 实现遍历打印
import java.util.Scanner;
/**
* @author WHD
* @description TODO
* @date 2024/1/5 9:16
* 数组类型的参数和返回值
*
* 需求:
* 1.编写方法实现统计一个学生的5门成绩 并且返回
* 2.编写方法实现接收用户输入的5门成绩 实现遍历打印
*/
public class TestArrayParamAndReturnValue {
/**
* 接收用户输入的5门成绩 需要返回值 但是不需要参数
* @return
*/
public static double[] inputScores(){
// 定义数组用于接下类保存成绩
double [] scores = new double[5];
Scanner input = new Scanner(System.in);
for(int i = 0;i < scores.length;i++){
System.out.println("请输入第" + (i + 1) + "门成绩");
scores[i] = input.nextDouble();
}
return scores;
}
/**
* 打印成绩的方法 需要参数 但是不需要返回值
* @param scores
*/
public static void printScores(double [] scores){
for(int i = 0;i < scores.length;i++){
System.out.println("第" + (i + 1) + "门成绩为:" + scores[i]);
}
}
public static void main(String[] args) {
double [] scores = inputScores();
printScores(scores);
}
}
11.值传递和引用传递的区别?
面试题:值传递和引用传递的区别?
基本数据类型传参属于值传递 传递的是一个值的副本 值的拷贝 在方法中对值的改变 不会影响原变量
引用数据类型传参属于引用传递 传递的是一个地址值 在方法根据地址值所做的操作 将影响所有指向此地址的变量
String类型是特殊的引用数据类型 作为参数传递不会影响原变量
Java官方明确说明了,Java中只有值传递,没有引用传递,所谓的引用传递其实也属于值传递
只不过这个值是一个:地址值
/**
* @author WHD
* @description TODO
* @date 2024/1/5 9:34
* 面试题:值传递和引用传递的区别?
* 基本数据类型传参属于值传递 传递的是一个值的副本 值的拷贝 在方法中对值的改变 不会影响原变量
* 引用数据类型传参属于引用传递 传递的是一个地址值 在方法根据地址值所做的操作 将影响所有指向此地址的变量
* String类型是特殊的引用数据类型 作为参数传递不会影响原变量
*
*
* Java官方明确说明了,Java中只有值传递,没有引用传递,所谓的引用传递其实也属于值传递
* 只不过这个值是一个:地址值
*/
public class TestInterview {
public static void m1(int num){
num++;
System.out.println("num = " + num);
}
public static void m2(int [] nums){
for (int i = 0; i < nums.length; i++) {
nums[i]++;
}
}
public static void main(String[] args) {
int a = 10;
m1(a);
System.out.println("a = " + a);
System.out.println("----------------------------------");
int [] b = {1,2,3,4,5};
m2(b);
for (int i = 0; i < b.length; i++) {
System.out.print(b[i] + "\t");
}
System.out.println();
}
}
12.可变长参数
可变长参数:可以接收0个或者多个相同类型的实参 最终实现还是数组 所以和数组的使用方式一致
要求:
1.形参列表中只能有一个可变长参数
2.必须书写在形参列表的末尾
说明:现阶段使用不到 后续讲解到反射 将大量的使用到可变长参数
/**
* @author WHD
* @description TODO
* @date 2024/1/5 10:17
* 可变长参数:可以接收0个或者多个相同类型的实参 最终实现还是数组 所以和数组的使用方式一致
* 要求:
* 1.形参列表中只能有一个可变长参数
* 2.必须书写在形参列表的末尾
*
* 说明:现阶段使用不到 后续讲解到反射 将大量的使用到可变长参数
*/
public class TestChangeableParam {
public static void m1(int a,int ... args){
System.out.println("m1方法开始执行");
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
System.out.println("m1方法执行完毕");
}
public static void main(String[] args) {
m1(1,2,3,4,5,6,7,8,11,2,3);
}
}
13.排序算法
13.1 冒泡排序
冒泡排序:两个相邻的元素比较大小,如果条件成立,则交换位置。
外层循环控制比较的轮数:长度 - 1 (n - 1)
内层循环控制每一轮比较的次数:最多的一次为 长度-1 后续每一轮都递减1 n - 1 - ?(递增的值)
外层循环:n - 1
内层循环:n - 1 - i
for(n - 1){
for(n - 1 -i){
if(条件成立){
交换位置;
}
}
}
/**
* @author WHD
* @description TODO
* @date 2024/1/5 10:28
* 冒泡排序:两个相邻的元素比较大小,如果条件成立,则交换位置。
*
* 外层循环控制比较的轮数:长度 - 1 (n - 1)
* 内层循环控制每一轮比较的次数:最多的一次为 长度-1 后续每一轮都递减1 n - 1 - ?(递增的值)
*
*
* 外层循环:n - 1
* 内层循环:n - 1 - i
*
* for(n - 1){
* for(n - 1 -i){
* if(条件成立){
* 交换位置;
* }
* }
* }
*
*
*/
public class BubbleSort {
public static void main(String[] args) {
int [] nums = {89,44,55,74,12,63,220,12,3};
for(int i = 0;i < nums.length - 1;i++){ // 控制的轮数 为 n - 1 相当于行
for(int j = 0;j < nums.length - 1 - i;j++){ // 控制的每轮比较的次数 相当于列
if(nums[j] < nums[j + 1]){
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
System.out.println("第" + (i + 1) + "轮比较完成以后,顺序为:" + Arrays.toString(nums));
}
System.out.println("-------------------排序完成----------------------");
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + "\t");
}
}
}
13.2 冒泡排序优化
因为冒泡排序都是两个相邻的元素比较,且每一轮只能确定一个元素的位置,所以正常情况下,必须要比较完成长度-1轮,但有些情况不需要比较长度-1轮,即已经排列正确,我们可以进行优化,以减少不必要的比较的轮数。
思路:在外层循环中加入布尔类型的变量,初始值为true,当内层条件成立,则表示需要交换位置,改变布尔变量的值,在一轮比较完成以后,对布尔变量的值判断,如果还未true,则表示没有交换一次位置,也就表示顺序已经正确,则可以提前结束循环。
import java.util.Arrays;
/**
* @author WHD
* @description TODO
* @date 2024/1/5 11:36
* 冒泡排序完善
*/
public class BubbleSortPerfection {
public static void main(String[] args) {
int [] nums = {89,44,55,74,12,63,220,12,3};
for(int i = 0;i < nums.length - 1;i++){ // 控制的轮数 为 n - 1 相当于行
boolean flag = true; // 定义布尔类型变量 标记
for(int j = 0;j < nums.length - 1 - i;j++){ // 控制的每轮比较的次数 相当于列
if(nums[j] < nums[j + 1]){
flag = false; // 如果条件成立 则表示需要交换位置 即表示顺序还未排列正确
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
System.out.println("第" + (i + 1) + "轮比较完成以后,顺序为:" + Arrays.toString(nums));
if(flag){
break;
}
}
System.out.println("-------------------排序完成----------------------");
for (int i = 0; i < nums.length; i++) {
System.out.print(nums[i] + "\t");
}
}
}
13.3 选择排序
import java.util.Arrays;
/**
* @author WHD
* @description TODO
* @date 2024/1/5 13:53
*
* 回顾冒泡排序是如何实现的?
* 冒泡排序是两个相邻的元素比较大小,如果需要交换位置,则会立即交换,这样就会出现某些元素移动很多次的现象
*
* 选择排序:固定位置的元素,依次与其他位置的元素比较大小,遇到需要交换位置的元素,
* 不会立即交换位置,而是交换比较的元素,等待一轮比较完成以后,再交换一次位置。
*
* 分析:选择排序可以理解为两个元素的比较 分别为元素A 和 元素B
* 元素A : 从第一个 元素开始 到倒数第二个元素 都将充当一遍元素A 0 n - 1
* 元素B : 从元素A后边相邻的位置开始 直到最后一个元素 i + 1 n
* 外层循环属于比较的元素A
* 内层循环属于比较的元素B
*
*/
public class SelectionSort {
public static void main(String[] args) {
int [] nums = {-99,89,44,55,74,12,63,220,3};
int count = 0;
for(int i = 0;i < nums.length - 1;i++){ // 元素A
int index = i; // 定义变量index 每轮比较开始 都设定为和i相同 用于作为交换下标
for(int j = i + 1;j < nums.length;j++){ // 元素B
if(nums[index] > nums[j]){
index = j; // 将更小的 或者 更大的 元素的下标 赋值给index 下一次比较将使用新的元素 继续往后比
}
}
if(index != i){
count++;
int temp = nums[index];
nums[index] = nums[i];
nums[i] = temp;
}
System.out.println("第" + (i + 1) + "次比较完成以后顺序为:" + Arrays.toString(nums));
}
System.out.println(Arrays.toString(nums));
System.out.println("一共交换了" + count + "次位置");
}
}
13.4 算法复杂度
13.5JDK提供的排序
JDK提供的排序:Arrays.sort() 升序排序 底层实现为快速排序
import java.util.Arrays;
/**
* @author WHD
* @description TODO
* @date 2024/1/5 14:41
* JDK提供的排序:Arrays.sort() 升序排序 底层实现为快速排序
*/
public class TestArraysSort {
public static void main(String[] args) {
int [] nums = {-99,89,44,55};
Arrays.sort(nums);
System.out.println(Arrays.toString(nums));
int [] newNum = new int[nums.length];
// 定义i从0开始 j从长度-1开始
// 循环条件为 循环次数
// i递增 j递减
for(int i = 0,j = nums.length -1; i < nums.length; i++,j--){
newNum[i] = nums[j]; // 将原数组最后的元素 赋值给新数组第一个位置的元素
}
System.out.println(Arrays.toString(newNum));
}
}
14.二维数组(了解)
二维数组:数组中的元素还是一维数组
/**
* @author WHD
* @description TODO
* @date 2024/1/5 15:21
* 二维数组:数组中的元素还是一维数组
*/
public class Test2DArray {
public static void main(String[] args) {
int [] arr1 = {1,2,3,4,5};
int [][] arr2 = {{11,22} , {1,2,3,4,5} ,{666,999,888}};
System.out.println(arr2[0]);
System.out.println(arr2[0][0]);
System.out.println(arr2[0][1]);
System.out.println(arr2[1]);
System.out.println(arr2[1][0]);
System.out.println(arr2[1][1]);
System.out.println(arr2[1][2]);
System.out.println(arr2[1][3]);
System.out.println(arr2[1][4]);
System.out.println(arr2[2]);
System.out.println(arr2[2][0]);
System.out.println(arr2[2][1]);
System.out.println(arr2[2][2]);
System.out.println("-----------------------------------");
for(int i = 0;i < arr2.length;i++){
for(int j = 0;j < arr2[i].length;j++){
System.out.print(arr2[i][j] + "\t");
}
System.out.println();
}
}
}
二维数组的定义
NullPointerException:空指针异常,只要使用一个指向为null的引用数据类型,继续访问任何的属性,方法,
或者使用一个指向为null的数组,存值,取值,就会出现空指针异常。
/**
* @author WHD
* @description TODO
* @date 2024/1/5 15:27
* 二维数组的定义
*
* NullPointerException:空指针异常,只要使用一个指向为null的引用数据类型,继续访问任何的属性,方法,
* 或者使用一个指向为null的数组,存值,取值,就会出现空指针异常。
*/
public class Test2DArrayDefine {
public static void main(String[] args) {
int [] nums = new int[3]; // 0 0 0
// 方式1 : 先声明 再分配空间 高维度的长度必须指定 低维度的长度可以临时指定
int [][] arr1;
arr1 = new int[3][];
System.out.println(arr1[0]);
System.out.println(arr1[1]);
System.out.println(arr1[2]);
// NullPointerException
arr1[0] = new int[5];
arr1[0][0] = 11;
arr1[0][1] = 12;
arr1[0][2] = 13;
arr1[0][3] = 14;
arr1[0][4] = 15;
arr1[1] = new int[4];
arr1[1][0] = 33;
arr1[1][1] = 33;
arr1[1][2] = 33;
arr1[1][3] = 33;
arr1[2] = new int[3];
arr1[2][0] = 666;
arr1[2][1] = 666;
arr1[2][2] = 666;
// 方式2 连声明 带开辟空间 高维度的长度必须指定 低维度的长度也可以立即指定
int [][] arr2 = new int[3][2];
for(int i = 0;i < arr2.length;i++){
for(int j = 0;j < arr2[i].length;j++){
System.out.print("*");
}
System.out.println();
}
// 方式3 声明并且赋值 繁琐
int [][] arr3 = new int[][]{ {1}, {22,22,33} , {33,555,666} };
// 方式4 声明并且赋值 简单
int [][] arr4 = { {1}, {22,22,33} , {33,555,666} };
}
}
15.Arrays类
Arrays类是JDK提供的数组工具类 位于java.util包中 使用此类必须导包
binarySearch() 使用二分法查找指定元素在数组中的位置 使用二分法的前提为 数组必须是有序的
toString() 返回指定数组的字符串形式
sort() 升序排序
copyOf() 复制数组
fill() 填充数组
import java.util.Arrays;
/**
* @author WHD
* @description TODO
* @date 2024/1/5 15:49
* Arrays类是JDK提供的数组工具类 位于java.util包中 使用此类必须导包
*
* binarySearch() 使用二分法查找指定元素在数组中的位置 使用二分法的前提为 数组必须是有序的
* toString() 返回指定数组的字符串形式
* sort() 升序排序
* copyOf() 复制数组
* fill() 填充数组
*/
public class TestArrays {
public static void main(String[] args) {
int [] nums = {9,5,3,1,8,6,4,2};
Arrays.sort(nums);
System.out.println(Arrays.toString(nums));
// 查找元素5在数组中的下标
System.out.println(Arrays.binarySearch(nums, 1));
int[] newNums = Arrays.copyOf(nums, 10);
System.out.println(Arrays.toString(newNums));
// 填充元素 使用666填充newNums数组 即将所有的元素都改为666
Arrays.fill(newNums, 666);
System.out.println(Arrays.toString(newNums));
}
}
16. 二分查找
二分查找:将一个有序的序列,一分为二,如果查找的元素小于中间值,则从左边查找,如果大于中间值,则从右边查找
如果等于中间值,则直接返回对应的下标。重复以上过程
/**
* @author WHD
* @description TODO
* @date 2024/1/5 16:00
* 二分查找:将一个有序的序列,一分为二,如果查找的元素小于中间值,则从左边查找,如果大于中间值,则从右边查找
* 如果等于中间值,则直接返回对应的下标。重复以上过程
*/
public class TestBinarySearch {
public static void main(String[] args) {
int [] nums = {1,2,3,4,5,6,7,8};
System.out.println(binarySearch(nums, 4));
}
public static int binarySearch(int [] nums,int num){
// 定义起始位置
int begin = 0;
// 定义结束位置
int end = nums.length -1;
// 定义中间位置
int middle = (begin + end) / 2;
// 定义index 作为最终的返回值 初始值为-1
int index = -1;
// begin通常情况下 小于end
// 因为最终二分的结果 就算是剩下一个元素 那么这个元素 既是begin 又是end 所以是等于
// 所以最终的条件为 <=
// 绝对不可能 begin 大于end
while(begin <= end){
if(num > nums[middle]){
begin = middle + 1;
}else if(num < nums[middle]){
end = middle - 1;
}else {
index = middle;
break;
}
// 每次更新完 begin 或者 end之后 中间值 也必须重新计算 所以 再次 (begin + end) / 2
middle = (begin + end) / 2;
}
return index;
}
}