目录
前言
冒泡排序是一个非常经典的排序算法,在我们刚接触编程的时候基本都会学到这个算法,今天本文介绍一下冒泡排序以及冒泡排序的优化。
提示:以下是本篇文章正文内容,下面案例可供参考
一、冒泡排序
冒泡排序就是对整个数列进行遍历,每次比较相邻两个数的大小,如果后面一个数字比前面一个数字大,那么就交换它们的位置,否则就不交换,每次遍历完成之后,就会开启下一轮优化。因此在实现这个排序时,我们一般会使用两个for循环,一个for循环控制遍历的轮数,另外一个for循环控制遍历的次数。基础代码如下:
public static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length; 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;
}
}
}
System.out.println("排序后的数组为:" + Arrays.toString(arr));
}
从代码中可以看出, 因为冒泡排序每次都要完全遍历,所以在面对一个已经排序好的数列或者有一部分已经排序好的数列时,它仍然会一直遍历,就直接增加了运算量。因此本文再介绍一下对冒牌排序的优化。
从图片中可以看出,冒泡排序的优化思路主要就是针对轮数和次数的优化,如何减小遍历轮数和比较次数就成为了优化的重点。
二、冒泡排序的优化
1.轮数优化
对于冒泡排序轮数的优化,我们可以这样思考。如果这个数列在某一次比较之后,就没有再交换位置,那么我们其实就可以认为从这次交换位置之后的序列已经排序完成了,后边就不需要再进行下一轮排序了。因此我们可以设置一个标志量,当这个标志量在某一轮中没有发生变化,那么就说明不需要进行下一轮了。
轮数优化之后的代码如下:
public static void bubbleSortOptimization(int[] arr) {
for (int i = 0; i < arr.length; i++) {
boolean flag = true;
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;
flag = false;
}
System.out.println("交换第"+ (j + 1) +"次");
}
if (flag) {
break;
}
}
System.out.println("优化排序后的数组为:" + Arrays.toString(arr));
}
从这段代码中可以看出,我们设置了一个boolean类型的标志量flag,在每次有位置交换时,将 flag的值赋为false。当有一轮flag为true时,就说明这一轮没有位置交换,后面的序列都已经排序完成。因此可以直接结束,不用进行下一轮。
2.次数优化
我们上面讲解了怎样优化轮数,在这里讲解一下怎么优化次数,对次数的优化我们可以这样考虑。如果有一次交换位置之后,后面就没有再交换次数了,但我们的程序在下一轮依旧会将这次交换位置之后的数字进行遍历和比较大小。因此我们可以考虑在每次交换位置之后用一个变量记录下最后一次交换的位置,当下一轮次数比较进行到这个地方时,后面就可以不用比较了。因为在上一轮后面都没有进行交换位置,所以后面的数字都是已经排序好了的。
次数优化后的代码如下:
public static void bubbleSortOptimization2(int[] arr) {
// 定义每一轮比较次数的边界
int index = arr.length - 1;
for (int i = 0; i < arr.length; i++) {
boolean flag = true;
// 定义每次最后比较的下标
int m = 0;
for (int j = 0; j < index; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = false;
m = j;
}
}
index = m;
if (flag) {
break;
}
}
System.out.println("优化排序后的数组为:" + Arrays.toString(arr));
}
从代码中我们可以看出,首先定义一个边界量index,再在第一个for循环中定义一个最后比较的下标,记录下每次最后比较的下标之后,在内部for循环结束时赋值给index,就可以限制下一轮比较次数的循环,同时也就优化了比较次数。
总结
以上就是今天要讲的内容,本文简单介绍了冒泡排序以及它的优化思路以及代码实现。