每轮选择当前位置,开始找后面的较小值与该位置进行交换。
第一轮:选择当前位置,当前位置是5,所以5与1比较,大于1,所以5与1进行交换。

5与1交换后,1就在当前位置,因此,1与后面的所有值进行比较,后面的值都大于1,所以1的位置不变。

第二轮:选择当前位置,当前位置是5,所以5与3比较,大于3,所以5与3进行交换

5与3交换后,3就在当前位置,因此,3与后面的所有值进行比较,后面的2小于3,所以3与2进行交换

第三轮:选择当前位置,当前位置是5,所以5与3比较,大于3,所以5与3进行交换

确定总共需要选择几轮:数组的长度 -1。
控制每轮从当前位置为基准,与后面元素选择几次。
package com.app.d8_sort_binarysearch;
import java.util.Arrays;
/**
目标:学会使用选择排序的方法,对数组进行排序
*/
public class Demo1 {
public static void main(String[] args) {
// 1、定义数组,传入一组数据
int[] numbers = {5, 1, 3, 2};
// 0 1 2 3
// 2、输出原数组内容
System.out.println("排序前:" + Arrays.toString(numbers));
// 3、定义外部for循环,控制选择几轮:数组长度 -1
for (int i = 0; i < numbers.length -1; i++) {
// i = 0 j = 1 2 3
// i = 1 j = 2 3
// i = 2 j = 3
// 4、定义内部for循环,控制选择几次:当前位置 +1,也就是后一位
for (int j = i+1; j < numbers.length; j++) {
// 当前位置:numbers[i]
// 5、如果后面有比当前位置更小的数据,则进行交换
if (numbers[j] < numbers[i]){
// 交换位置
// a、先定义一个临时变量将当前位置的数据存一下
int temp = numbers[i];
// b、再将后面的数据 赋值给 当前的位置
numbers[i] = numbers[j];
// c、最后将当前位置的数据 赋值给 后面的位置
numbers[j] = temp;
}
}
}
// 6、全部交换完成,输出排序后的数组内容
System.out.println("排序后:" + Arrays.toString(numbers));
}
}
排序前:[5, 1, 3, 2]
排序后:[1, 2, 3, 5]
Process finished with exit code 0
需求:

结论:在数据量特别大的时候,基本查找从前往后寻找的性能是很差的!!
需求:

二分查找会定一个位置在首,定一个位置在尾。

之后会找,首和尾的一半的位置。

然后,发现数据3 小于 首和尾一半位置的数据,直接从左边开始找,将右边干掉。

因此,尾部的位置就是:一半的位置-1。

然后,又找首和尾的一半的位置。

之后,发现数据3 大于 首和尾一半位置的数据,直接从右边开始找,将左边干掉。

然后,首部的位置就是:一半的位置 +1。

最后,再找首和尾一半的位置,发现这个位置的数据刚好是3,因此将位置索引 2返回。

需求:

二分查找会定一个首位置和一个尾位置。

然后,发现数据11 大于 首和尾一半位置的数据,直接从右边开始找,将左边干掉。

之后,首位置就是:一半的位置 +1。

然后,又找首和尾一半的位置(折半)。

之后,发现数据11 大于 首和尾一半位置的数据,直接从右边开始找,将左边干掉。

然后,首位置就是:一半的位置 +1。

之后,又找首和尾一半的位置。

然后,发现数据11 大于 首和尾一半位置的数据,直接从右边开始找,将左边干掉。

此时,首位置就是:一半位置 +1,然后发现首尾位置重合了,因此,一半的位置还是自己,但是已经是最后一次查找了,数据还是不相等。

结论:二分查找正常的检索条件应该是首位置min <= 尾位置max,但是现在是 !=,因此属于找不到,元素不存在
package com.app.d8_sort_binarysearch;
import java.util.Arrays;
/**
目标:理解二分查找其执行原理
*/
public class Demo2 {
public static void main(String[] args) {
// 1、定义一个数组,传入一组数据
int[] arr = {34, 23, 566, 78, 11, 35, 66, 99};
// 2、二分查找的前提必须是排好序的数据,所以先排序
Arrays.sort(arr);
// 3、输出排序后的数组内容
System.out.println("排序后:" + Arrays.toString(arr));
// 排序后:[11, 23, 34, 35, 66, 78, 99, 566]
// 0 1 2 3 4 5 6 7 -1
// 5、调用二分查询的方法,查询要找的元素
int index1 = binarySearch(arr, 66);
int index2 = binarySearch(arr, 600);
System.out.println("该元素的位置索引:" + index1);
System.out.println("该元素的位置索引:" + index2);
// 6、判断该元素是否存在:
/*if (index > 0) {
// a、索引位置 大于 0,说明存在,输出该元素的位置索引
System.out.println("该元素的位置索引:" + index);
}else {
// c、索引位置 小于 0,说明不存在,提示查无此元素
System.out.println("查无此元素!");
}*/
}
/**
* 4、二分查找算法的实现方法
* @param arr 排序的数组
* @param data 要找的数组元素
* @return 如果元素存在,则返回元素的位置索引,否则返回-1。
*/
public static int binarySearch(int[] arr, int data) {
// a、定义首和尾的位置
int head = 0; // 首
int tail = arr.length - 1; // 尾
// b、定义循环: 当首位置 <= 尾位置时,开始二分查询(折半)
while (head <= tail) {
// c、找首和尾位置的一半的位置(中间索引)
int midIndex = (head + tail) / 2; // 中间索引 = (首索引 - 尾索引) / 2;
// d、当要找的元素 大于 中间索引位置的元素时:
if (data > arr[midIndex]) {
// (1) 说明要找的元素在尾位置那边,更新首位置的索引 = 中间位置的索引 +1
head = midIndex + 1;
}else if (data < arr[midIndex]){
// e、当要找的元素 小于 中间索引位置的元素时:
// (1) 说明要找的元素在首位置那边,更新尾位置的索引 = 中间位置的索引 -1
tail = midIndex - 1;
}else {
// f、当要找的元素 等于 中间索引位置的元素时:
// (1) 说明要找的元素已经找到了,返回该元素的位置索引
return midIndex;
}
}
// g、循环结束,说明仍然找不到要找的元素,因此查无此元素,返回-1
return -1;
}
}
排序后:[11, 23, 34, 35, 66, 78, 99, 566]
该元素的位置索引:4
该元素的位置索引:-1
Process finished with exit code 0
1、数组的二分查找的实现步骤是什么?
Lambda表达式是JDK8开始后的一种新语法形式。(匿名内部类被重写方法的形参列表)->{
被重写方法的方法体代码;
}
->是语法形式,无实际含义。
@FunctionalInterface注解,标记该接口必须是满足函数式接口。package com.app.d9_lambda;
/**
目标:学会使用Lambda表达式的标准格式简化匿名内部类的代码形式
*/
public class LambdaDemo2 {
public static void main(String[] args) {
// 1、Lambda只能简化接口中只有一个抽象方法的匿名内部类形式
// 匿名内部类形式
// Swimming s1 = new Swimming() {
// @Override
// public void swim() {
// System.out.println("运动员游得飞快~~~~~");
// }
// };
// go(s1);
// 第一次简化:lambda表达式
Swimming s2 = () -> {
System.out.println("运动员游得飞快~~~~~");
};
go(s2);
System.out.println("-------------------------");
// 第二次简化:匿名内部类形式作为实参传入go方法
// go(new Swimming() {
// @Override
// public void swim() {
// System.out.println("学生游得很开心~~~~~");
// }
// });
// 第三次简化:lambda表达式
go(() -> {
System.out.println("学生游得很开心~~~~~");
});
}
public static void go(Swimming s){
System.out.println("开始...");
s.swim();
System.out.println("结束...");
}
}
@FunctionalInterface // 一旦定义了这个注解,必须是函数式接口,且内部只能有一个抽象方法
interface Swimming{
void swim();
}
开始...
运动员游得飞快~~~~~
结束...
-------------------------
开始...
学生游得很开心~~~~~
结束...
Process finished with exit code 0
1、Lambda表达式的基本作用?
2、Lambda表达式有什么使用前提?
3、Lambda表达式的好处?


进一步在Lambda表达式的基础上继续简化:
参数类型可以省略不写。

如果只有一个参数,参数类型可以省略,同时 () 也可以省略。

如果Lambda表达式的方法体代码只有一行代码,可以省略 {} 不写,同时要省略 ;不写。

如果Lambda表达式的方法体代码只有一行代码,可以省略 {} 不写。此时,如果这行代码是 return 语句,必须省略 return不写,同时也可以省略 ;不写。

