Array工具类
2.1常见的算法
排序算法:
冒泡排序算法
选择排序算法
查找算法:
二分法查找
2.2算法实际上在java中不需要精通,因为java中已经封装好了,要排序就调用方法就行。
例如:java中提供了一个数组工具类
java.util.Arrays
Arrays是一个工具类
其中有一个sort()方法,可以排序。静态方法,直接使用类名调用就号。
冒泡排序算法:
大的气泡先出去,然后再小的气泡
代码例:
/*
冒泡排序算法
1、每一次循环结束之后,都要找出最大的数据,放到参与比较的这堆数据的最右边。(冒出最大的气泡)
2、核心:
拿着左边
原始数据:3,2,7,6,8
拿着3和右边相邻2进行比较,如果3>2交换位置。交换位置后的数据:2,3,7,6,8
继续拿着上一次比较之后的结果中,右边较大的数据和后续的数据比较。
第一次循环:
2,3,7,6,8 (3和2比较,2<3 交换位置)
2,3,7,6,8 (虽然不需要交换位置,但3和7需要比较一次。)
2,3,6,7,8 (7和6交换位置)
2,3,6,7,8 (虽然不需要交换位置,但7和8需要比较一次。)
经过第一次循环,最大的已经在最右边,参与比较的数据:2,3,6,7
第二次循环 2,3,6,7
2,3,6,7 (2和3比较,不需要交换位置)
2,3,6,7 (3和6比较,不需要交换位置)
2,3,6,7 (6和7比较,不需要交换位置)
第三次循环 2 3 6
2,3,6 (2和3比较,不需要交换位置)
2,3,6 (3和6比较,不需要交换位置)
第四次循环: 2 3
2,3 (2和3比较,不需要交换位置)
参与比较数据 9 8 10 7 6 0 11
第一次循环:
8 9 10 7 6 0 11
8 9 10 7 6 0 11
8 9 7 10 6 0 11
8 9 7 6 10 0 11
8 9 7 6 0 10 11
8 9 7 6 0 10 11
最终冒出的最大数据在右边:
参与比较数据 8 9 7 6 0 10
第二次循环:
8 9 7 6 0 10
8 7 9 6 0 10
8 7 6 9 0 10
8 7 6 0 9 10
8 7 6 0 9 10
参与比较数据 8 7 6 0 9
第三次循环:
7 8 6 0 9
7 6 8 0 9
7 6 0 8 9
7 6 0 8 9
参与比较数据:7 6 0 8
第四次循环:
6 7 0 8
6 0 7 8
6 0 7 8
参与比较数据 6 0 7
第五次循环:
0 6 7
0 6 7
参与比较数据 0 6
第六次循环:
0 6
**/
public class BubbleSort {
public static void main(String[] args) {
//int类型的数组对象
int[] arr = {3, 2, 7, 6, 8};
int[] arr1 = {9, 8, 10, 7, 6, 0, 11};
//经过冒泡排序算法对以上数组的元素进行排序
//冒泡排序算法的核心是什么?
int count = 0;
int count2 = 0;
for (int i = arr1.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {//正好不会越界
count++;
if (arr1[j] > arr1[j + 1]) {
int temp;
temp = arr1[j];
arr1[j] = arr1[j + 1];
arr1[j + 1] = temp;
count2++;
}
}
}
System.out.println("比较次数: " + count);
System.out.println("交换次数: " + count2);
for (int i = 0; i < arr1.length ; i++) {
System.out.println(arr1[i]);
}
}
}
运行成功截图:
选择排序算法:
/*
选择排序:
每一次都从这堆参与比较的数字中找出最小值,
拿着这个最小值和前面元素交换位置。
选择排序比冒泡排序好在,每次排序都是有意义的。
*/
public class SelectSort {
public static void main(String[] args) {
int [] arr = {9, 8, 10, 7, 6, 0, 11};
int count = 0;
for(int i = 0; i < arr.length - 1;i++) {
//i是 0 1 2 3
//i正好是"参加比较这堆元素中"最左边的那个元素下标
//这里看成i是我们需要比较的最左边的元素,我们此时把他当作最小的,和其他进行比较
//假设i下标位置上的元素是最小的
int min = i;
for (int j = i + 1; j < arr.length; j++) {
count++;
if (arr[j] < arr[min]) {
min = j;
}
}
//如果我们的假设失败,i位置不是最小,那我们就通过上面的代码通过比较,使得此时的min下标是最小,并且通过下面代码交换位置
if (min != i) {
int temp;
temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
}
System.out.println("比较次数:" + count);
for (int i = 0; i <arr.length ; i++) {
System.out.println(arr[i]);
}
}
}
运行成功截图:
冒泡排序和选择排序的对比:
两个算法的比较次数都为21次,但是选择排序是可以直接把最小的元素放到最左边,而冒泡排序需要一直对比,一旦右边的数字比左边的数字大便要交换,因此选择排序算法的效率会更高一点,少了很多交换的次数。
二分法查找算法:
/*
1、数组工具类:自己写的。不是SUN的。
2、关于查找算法中的:二分法查找。
10(下标0) 11 12 13 14 15 16 17 18 19 20(下标10) arr数组。
通过二分法查找,找出18这个元素的下标:
(0 + 10) / 2 --> 中间元素的下标: 5
拿着中间这个元素和目标要查找的元素进行对比:
中间元素是:arr[5] --> 15
15 < 18(被查找的元素)
被查找的元素18在目前中间元素15的右边。
所以开始元素的下标从0变成 5 + 1.
再重新计算一个中间元素的下标:
开始下标是:5 + 1
结束下标是:10
(6 + 10) / 2 --> 8
8下标对应的元素arr[8]是18
找到的中间元素正好和被找的的元素18相等,表示找到了:下标为8
二分法查找的终止条件:一直折半,直到中间的那个元素恰好是被查找的元素。
3、二分法查找算法是基于排序的基础之上。(没有排序的数据是无法查找的。)
*/
public class ArraySearchTwo {
public static void main(String[] args) {
int[] arr = {100, 200, 230, 235, 600, 1000, 2000, 9999};
//找出arr这个数组中200所在下标
//调用方法
int index = binarySearch(arr, 9999);
System.out.println(index == -1 ? "该元素不存在" : "该元素下标" + index);
}
/*
arr 被查找数组
dest 目标元素
*/
public static int binarySearch(int[] arr, int dest) {
//开始下标
int begin = 0;
//结束下标
int end = arr.length - 1;
//中间元素下标
while (begin <= end) {
int mid = (begin + end) / 2;
if (arr[mid] == dest) {
return mid;
} else if (arr[mid] < dest) {
//目标再"中间"的右边
//开始元素下标需要发生变化(开始元素的下标需要重新赋值)
begin = mid + 1;
} else {
//arr[mid] > dest
//目标再"中间"的左边
//修改结束元素下标
end = mid - 1;
}
}
return -1;
}
}
二分法查找算法总结:
二分法查找适用于数组从小到大的排序,如果是乱序,那么便无法使用二分法查找,二分法查找的效率比遍历的效率高不少,不需要一个个来查找元素单位。
大总结:
算法本身的逻辑不难,但是要通过代码实现,那么一些循环的结束条件等,我们都要经过一些思考才能得出,类似于冒泡排序和选择排序的循环,我们的 j 和 i都是有一定的关联的,特别是冒泡排序算法中,设定的两个循环的条件比较恰当以及精妙。