前言:
- 冒泡排序思想:
让数组当中相邻的两个数进行比较,数组当中比较小的数值向下沉,数值比较大的向上浮!外层for循环控制循环次数,内层for循环控制相邻的两个元素进行比较。 - 举个简单的例子:
台球桌上摆着一排顺序不一的台球,需要将他们按照顺序摆好。
a. 拿起第一、二个位置的球,将数字小的放在第一个位置,数字大的放在第二位置。
b. 在拿起第二、三个位置的球,同样将数字小的放在第二个位置,数字大的放在第三位置。
c. 依次类推,最后将数字最大的球放在最后的位置。
d.在从头开始,依次执行a,b操作,因为操作c已经挑出最大数组的球了,因此我们无需比较最后位置的球,将本轮最大位置的球放在倒数第二个位置即可。
e.重复d操作,直到所有的球均排序好。
动图演示:
图片来自菜鸟教程: https://www.runoob.com/w3cnote/bubble-sort.html
图文码示例:
-
假设我们有一个这样的数组: {9,8,7,6,5,4,3,2,1}
-
编写冒泡类,将其排序:
/**
* 冒泡排序
*/
public class BubbleSort {
public static void main(String[] args) {
int[] arr = new int[]{9,8,7,6,5,4,3,2,1};
// 排序数组
BubbleSort.sort(arr);
// 打印结果
System.out.println(Arrays.toString(arr));
}
/**
* 冒泡执行类, 正序
* @param arr
* @return
*/
public static int[] sort(int[] arr){
int temp;
// 外层控制循环次数,总次数为 arr.length-1
for (int i=0; i<arr.length; i++){
// 内层循环,所需要比较的次数
for (int j=0; j < arr.length-1-i; j++ ){
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
}
-
打印结果:
-
图文示例:
至此 冒泡排序学习结束。
扩展:
- 熟悉 Array 的同学知道,Arrays.sort() 也可以对数组排序,上面冒泡排序可以修改为:
public static void main(String[] args) {
int[] arr = new int[]{9,8,7,6,5,4,3,2,1};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
打印结果:
2. 那么问题来了, 冒泡 和 Arrays.sort() 对数组的排序谁更快那, 我们通过JMH 来测试一下:
【Java微基准测试框架JMH】
测试代码:
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
/**
* 冒泡功能 和 Arrays.sort(arr); 效率测试
*/
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 3)
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)
@Threads(1)
@Fork(1)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)
public class BubbleSortBenchmark {
@Param({"100", "1000", "10000"})
private int arrLength;
private int[] numbers;
/**
* 初始化数组
*/
@Setup
public void prepare() {
numbers = new int[arrLength];
Random random = new Random();
for (int i = 0; i < numbers.length; i++) {
numbers[i] = random.nextInt(1000); //Integer.MAX_VALUE);
}
}
@Benchmark
public void testBubbleSort(){
BubbleSort.sort(numbers);
}
@Benchmark
public void testArraySort(){
Arrays.sort(numbers);
}
public static void main(String[] args) throws RunnerException {
Options options = new OptionsBuilder()
.include(BubbleSortBenchmark.class.getSimpleName())
.build();
new Runner(options).run();
}
}
重要打印结果:
其中
1. Benchmark: 表示执行的方法。
2. arrLength: 参数值
3. Units: 表示每毫秒执行的次数
4. Score:与Units一起解释,这里表示 每毫秒执行的次数
其中当我们的数组长度 从 100、1000、10000 变化时,Arrays.sort()每毫秒执行的次数,总是冒泡排序高几十倍数,结果显而易见了,Arrays.sort()效率远远高于冒泡排序!!! 再见冒泡排序!