前言:
- 冒泡排序思想:
讓數組當中相鄰的兩個數進行比較,數組當中比較小的數值向下沉,數值比較大的向上浮!外層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()效率遠遠高於冒泡排序!!! 再見冒泡排序!