视频链接:https://www.bilibili.com/video/BV1Rx411876f?p=1
视频范围P576 - P583
1.冒泡排序算法
- 每一次循环结束之后,都要找出最大的数据,放到参与比较的这堆数据的最右边。(冒出最大的那个气泡)
- 核心:拿着左边的数字和右边的数字比对,当左边 > 右边的时候,交换位置
package array;
public class BubbleSort {
public static void main(String[] args) {
//静态初始化数组
int[] array = {10,5,65,54,1,2,9};
//定义计数器,记录一共比较了多少次
int count = 0;
//冒泡排序算法
for (int i = array.length - 1; i > 0 ; i--) {
for (int j = 0; j < i; j++) {
//不管是否需要交换位置,肯定要比较一次
count++;
//交换位置
if (array[j] > array[j + 1]){
int temp;
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
System.out.println("比较次数:" + count);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
运行结果:
2.选择排序算法
- 每一次从这堆“参与比较的数据”当中找出最小值,拿着这个最小值和“参与比较的这堆最前面的元素”交换位置
- 选择排序比冒泡排序好在:每一次的交换位置都是有意义的
- 冒泡排序和选择排序实际上比较的次数没变,但是选择排序的交换次数变少了
视频中的算法:
package array;
public class SelectSort {
public static void main(String[] args) {
int[] array = {4,5,9,2,45,62,1,6,8,7,12};
int count = 0;
//选择排序算法
for (int i = 0; i < array.length - 1; i++) {
int min = i;
for (int j = i + 1; j < array.length; j++) {
count++;
if (array[j] < array[min]){
min = j;//最小值的元素下标j
}
}
if (min != i){
int temp;
temp = array[min];
array[min] = array[i];
array[i] = temp;
}
}
System.out.println("比较次数:" + count);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
自己编写的算法:
package array;
public class SelectSort {
public static void main(String[] args) {
int[] array = {4,5,9,2,45,62,1,6,8,7,12};
int count = 0;
for (int i = 0; i < array.length - 1; i++) {
int idex = i;
int min = array[i];
for (int j = i; j < array.length - 1; j++) {
count++;
if (array[j + 1] <= min){
idex = j + 1;
min = array[idex];
}
}
if (idex == i){
continue;
}else{
int temp;
temp = array[idex];
array[idex] = array[i];
array[i] = temp;
}
}
System.out.println("比较次数:" + count);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
运行结果:
3.二分(折半)查找算法
数组的元素查找有两种方法:
- 第一种:一个一个挨着找,直到找到为止
- 第二种:二分法查找(算法),这个效率较高
3.1 不使用二分法
package array;
public class ArraySearch {
public static void main(String[] args) {
int[] array = {4,5,9,2,45,62,1,6,8,7,12};
int index = arraySearch(array,45);
System.out.println(index == -1?"该元素不存在!" : "该元素下标是:" + index);
}
/**
* 从数组中检索某个元素的下标(返回第一个元素的下标)
* @param array 被检索的数组
* @param num 被检索的元素
* @return 大于等于0的数表示元素的下标,-1表示该元素不存在
*/
private static int arraySearch(int[] array, int num) {
for (int i = 0; i < array.length; i++) {
if (num == array[i]){
return i;
}
}
return -1;
}
}
运行结果:
3.2 二分法查找
- 二分法算法基于排序的基础之上(没有排序的数据是无法查找的)
- 二分查找效率要高于“一个挨着一个”的这种查找方法
- 二分法查找的终止条件:一直折半,直到中间的那个元素恰好是被查找的元素
- 在代码库中已经有了binarySearch函数
import static java.util.Arrays.binarySearch;
代码示例:
package array;
public class ArrayUtil {
public static void main(String[] args) {
int[] array = {1,5,45,63,88,120,180,320};
int index = binarySearch1(array,180);
System.out.println(index == -1?"该元素不存在!" : "该元素下标是:" + index);
}
/**
* 从数组中查找目标元素的下标
* @param array 被查找的数组(这个必须是已经排序的)
* @param dest 目标元素
* @return -1表示该元素不存在,其它表示返回该元素的下标
*/
private static int binarySearch1(int[] array, int dest) {
//开始下标
int begin = 0;
//结束下标
int end = array.length - 1;
//开始元素的下标只要在结束元素下标的左边,就有机会继续循环
while (begin <= end){
//中间元素下标
int mid = (begin + end) / 2;
if (array[mid] == dest){
return mid;
}else if (array[mid] < dest){
//目标在中间的右边
begin = mid + 1;
}else {
//目标在中间的左边
end = mid - 1;
}
}
return -1;
}
}
运行结果:
4.Arrays工具类的使用
- SUN公司为程序员写好了一个数组工具类 java.util.Arrays;
- 开发的时候参考API帮助文档
- 所有的方法都是静态的
package array;
import java.util.Arrays;
public class ArraysTest02 {
public static void main(String[] args) {
int[] array = {1,5,3,6,2,8,9,45,18,16,21};
//排序
Arrays.sort(array);
//输出
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]); //输出为:1 2 3 5 6 8 9 16 18 21 45
}
//二分查找
int index = Arrays.binarySearch(array,45);
//输出
System.out.println(index == -1?"该元素不存在!" : "该元素下标是:" + index);//该元素下标是:10
}
}