6第六天–常用Api和数组高级
6.1数组的高级操作–二分查找法
-
.二分查找法的前提
- 一个有序的数组
-
.二分查找
- 查找指定元素在数组中出现的索引位置,二分查找也叫折半查找,每次可以去掉一半的查找范围,从而提高查找的效率
-
二分查找的逻辑
数组内的元素一定要按照大小顺序排列(从小到大或从大到小),如果没有大小顺序,是不能使用二分查找法的
1,定义两个变量,表示要查找的范围。默认min = 0 , max = 最大索引
2,循环查找,但是min <= max
3,计算出mid的值
4,判断mid位置的元素是否为要查找的元素,如果是直接返回对应索引
5,如果要查找的值在mid的左半边,那么min值不变,max = mid -1.继续下次循环查找
6,如果要查找的值在mid的右半边,那么max值不变,min = mid + 1.继续下次循环查找7,当 min > max 时,表示要查找的元素在数组中不存在,返回-1.示例
public class MyBinarySearchDemo { public static void main(String[] args) { int [] arr = {1,2,3,4,5,6,7,8,9,10}; int number = 11; //1,我现在要干嘛? --- 二分查找 //2.我干这件事情需要什么? --- 数组 元素 //3,我干完了,要不要把结果返回调用者 --- 把索引返回给调用者 int index = binarySearchForIndex(arr,number); System.out.println(index); } private static int binarySearchForIndex(int[] arr, int number) { //1,定义查找的范围 int min = 0; int max = arr.length - 1; //2.循环查找 min <= max while(min <= max){ //3.计算出中间位置 mid int mid = (min + max) >> 1; //mid指向的元素 > number if(arr[mid] > number){ //表示要查找的元素在左边. max = mid -1; }else if(arr[mid] < number){ //mid指向的元素 < number //表示要查找的元素在右边. min = mid + 1; }else{ //mid指向的元素 == number return mid; } } //如果min大于了max就表示元素不存在,返回-1. return -1; }
6.2冒泡排序
62.1什么是冒泡排序
-
对要进行的排序数组中,相邻的数据进行两两比较,较大的数据放在后面,依次对所有的数据进行操作,直至所有数据按要求完成排序
-
冒泡排序的特点
-
共有n个数要比较n-1次
-
每一轮比较完毕,下一次就会少一个数据参加
-
示例
public class MyBubbleSortDemo2 { public static void main(String[] args) { int[] arr = {3, 5, 2, 1, 4}; //1 2 3 4 5 bubbleSort(arr); } private static void bubbleSort(int[] arr) { //外层循环控制的是次数 比数组的长度少一次. for (int i = 0; i < arr.length -1; i++) { //内存循环就是实际循环比较的 //-1 是为了让数组不要越界 //-i 每一轮结束之后,我们就会少比一个数字. for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } printArr(arr); } private static void printArr(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } } } private static void bubbleSort(int[] arr) { //外层循环控制的是次数 比数组的长度少一次. for (int i = 0; i < arr.length -1; i++) { //内存循环就是实际循环比较的 //-1 是为了让数组不要越界 //-i 每一轮结束之后,我们就会少比一个数字. for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } printArr(arr); } private static void printArr(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); }
-
6.3…递归
6.2.1.递归概念
-
可以说是自己调用自己的方法本身(类似于循环)
-
n提通过每次传入的参数不同,可以将复杂的问题解决
6.2.3递归解决问题的核心思想
- 将复杂的问题化成一个小的同类问题,通过求解规模小的同类问题的解
- 递归解决问题三大步骤
- 1.明确这个函数你想干什么
- 2.找到递归的结束条件(出口):找出参数为什么时,可以知道方法的结果,直接返回结果
- 3.找出方法的等价关系表达式:将大问题拆成小问题,决定每次调用方法时参数缩小的范围
注意:递归即使找到出口也不易循环次数太多
6.2.4递归的基本使用
-
求1-100之间的和
-
示例
public class MyFactorialDemo2 { public static void main(String[] args) { int sum = getSum(100); System.out.println(sum); } private static int getSum(int i) { //1- 100之间的和 //100 + (1-99之间的和) // 99 + (1- 98之间的和) //.... //1 //方法的作用: 求 1- i 之间和 if(i == 1){ return 1; }else{ return i + getSum(i -1); } } public static void main(String[] args) { int sum = 0; for (int i = 1; i <= 100; i++) { sum = sum + i; } System.out.println(sum); }
3.求5的阶乘
- 5 *4 *3 * 2 *1 并打印在控制台上
public class MyFactorialDemo3 {
public static void main(String[] args) {
int result = getJc(5);
System.out.println(result);
}private static int getJc(int i) {
//1,就是一定要找到出口.
if(i == 1){
return 1;
}else{
//2.就是递归的规则
return i * getJc(i - 1);
}
}
//54321
private static int getMultiply(int i){
int m=1;
while (i>1){
m=m*i;
i–;
}
return m;
}
经验:如果用循环解决问题不困难的话,就可以使用循环,如果解决困难,可以考虑递归
6.4快速排序
6.3.1什么是快速排序
- 冒泡排序是算法当中,一次循环结束就确定了最大值,也能确定了数组的最大值在数组中的位置
- 快速排序中,每一次递归时,以第一个数为基准数,找到数组中的所有比基准数小的数放在,左边。比基准数打的数放在右边,确定基准数的正确位置
- 核心步骤
- 从右开始找基准数的小的
- 从左开始找比基准数大的
- 进行红色继续左找,蓝色继续往右找,直到两个箭头指向同一个索引为止
- 红色继续左找,蓝色继续往右找,直到两个箭头指向同一个索引为止
- 基准数归位
6.5–Arrays
1.什么是Arrays类
- 该类把包含了用于操作数组的各种方法
2.Arrays常用方法
方法 | 说明 |
---|---|
public static String toString(int[] a) | 返回指定数组的内容的字符串表示形式 |
public static void sort(int[] a) | 按照数字顺序排列指定数组(底层使用快速排序的,打印是需要Arrays.toString方法以后才能打印) |
public static int binarySearch(int[] a, int key) | 利用二分查找返回指定元素的索引(前提数据按顺序排好) |
注意:如果binarySearch查找的数据不存在在这个数组中,将会返回(插入点-1)
插入点:原本在数据中应该出现的索引
6.6—Date
1.什么是Date类
- Date代表了一个特定的时间,精确到毫秒
2.时间换算单位
- 1秒=1000毫秒
3.Date类的构造方法
方法 | 说明 |
---|---|
public Date() | 创建Dated对象,默认存储当前时间,单位为毫秒 |
public Date(long date) | 创建的Date对象,并将其初始化从计算机起始时间起到指定毫秒数(你传入的参数)//Thu Jan 01 10:00:00 CST 1970 |
System.currentTimeMills也是获取当前时间的毫秒值//1602833680902
4.date成员方法
1.getTime(); 获取当前系统时间的毫秒数 从计算机基准时间1970 年1月1日00:00:00到当前时间
2.setTime(); 设置时间,传入的也是毫秒是 从计算机基准时间1970 年1月1日00:00:00
Date date= new Date();
date2.setTime(System.currentTimeMillis());
System.out.println(date2);//修改到当前时间
1.sett=