目錄
1.冒泡排序介紹
冒泡排序是一種比較簡單的排序方法,以數組升序的情況爲例,它的原理是從第一個元素開始,每個元素都與其相鄰的元素做比較,如果前一個元素比後一個元素大,則交換兩個元素的位置,每一輪排序都確定一個最大值。它是一種穩定的排序方法,因爲兩個元素相等時不會做交換,相對位置不會發生改變。
2. O(n^2)的實現方法
/**
* @author Zeng
* @date 2020/2/27 16:39
*/
public class BubbleSort1 {
public static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void bubbleSort(int[] arr){
for (int i = 0; i < arr.length; i++){
for (int j = 0; j < arr.length - i - 1; j++){
if(arr[j] > arr[j+1]){
swap(arr, j, j+1);
}
}
}
}
public static void main(String[] args) {
int[] arr = new int[]{5, 3, 1, 6, 2, 4};
bubbleSort(arr);
for (int i : arr) {
System.out.print(i+ " ");
}
}
}
//第1趟排序結果:3 1 5 2 4 6
//第2趟排序結果:1 3 2 4 5 6
//第3趟排序結果:1 2 3 4 5 6
//第4趟排序結果:1 2 3 4 5 6
//第5趟排序結果:1 2 3 4 5 6
//第6趟排序結果:1 2 3 4 5 6
3. 優化思路1:提前到達有序
如果數組本來就有序,那麼使用上面的代碼依舊會對數組進行6輪排序,但是一個元素都沒有交換,所以我們爲數組添加一個標誌tag,如果某一輪排序中沒有數組元素進行交換,那麼就代表此時的數組已經有序,無需進行下一輪的排序。
/**
* @author Zeng
* @date 2020/2/27 16:39
*/
public class BubbleSort2 {
public static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void bubbleSort(int[] arr){
//判斷某一輪排序有沒有進行元素交換,如果爲false則代表數組已有序
boolean flag;
for (int i = 0; i < arr.length; i++){
flag = false;
for (int j = 0; j < arr.length - i - 1; j++){
if(arr[j] > arr[j+1]){
swap(arr, j, j+1);
flag = true;
}
}
if(!flag){
return ;
}
System.out.print("第"+(i+1)+"趟排序結果:");
for (int k : arr) {
System.out.print(k+" ");
}
System.out.println();
}
}
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 6, 5};
bubbleSort(arr);
}
}
//第1趟排序結果:1 2 3 4 5 6
4. 優化思路2:獲取交換的最後一個元素下標
在某一趟排序中有可能在某個元素之後都沒有做交換操作,那麼可以知道該元素以後已經有序,下一輪排序不需要對該元素以後的其它元素做排序,所以我們可以用一個變量pos進行記錄當前一輪排序中交換元素的最後一個位置,每一輪排序只針對第1個元素到第pos個元素進行,第pos+1個元素開始已經保持有序,同樣我們採用優化思路1,如果某一趟排序沒有元素做交換,那麼證明數組已經有序,不需要進行下一輪的排序。
/**
* @author Zeng
* @date 2020/2/28 8:28
*/
public class BubbleSort3 {
public static void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void bubbleSort(int[] arr){
int position = arr.length - 1;
int tmpPosition = position;
boolean flag;
for (int i = 0; i < arr.length; i++){
flag = false;
for (int j = 0; j < tmpPosition; j++){
if(arr[j] > arr[j+1]){
swap(arr, j, j+1);
position = j;
flag = true;
}
}
if(!flag){
return ;
}
System.out.print("第"+(i+1)+"趟排序結果:");
for (int k : arr) {
System.out.print(k+" ");
}
System.out.println("最後交換元素的位置pos:"+position);
tmpPosition = position;
}
}
public static void main(String[] args) {
int[] arr = new int[]{3,2,1,5,4,6};
bubbleSort(arr);
}
}
//第1趟排序結果:2 1 3 4 5 6 最後交換元素的位置pos:3
//第2趟排序結果:1 2 3 4 5 6 最後交換元素的位置pos:0
5. 總結
冒泡排序是九大排序算法中較爲簡單的排序算法,但是也要考慮其優化,目前我只能想到這兩種優化方法,如果大家有其它優化思路可以分享給我,如果代碼有什麼錯誤歡迎指出,能力有限,時間有限,樂意與大家交流!