數據結構—排序之冒泡排序

數據結構—排序之冒泡排序

注:此文檔《數據結構與算法之美》的課上學習和自習總結的。屬於原創文章,如發現錯誤,請指出

系列文章
什麼是數據結構?什麼是算法?
數據結構—數組
數據結構—鏈表
數據結構—棧
數據結構—隊列
數據結構—排序

##冒泡排序

  • 冒泡排序:冒泡排序只會操作相鄰的兩個數據。每次冒泡操作都會對相鄰的兩個元素進行比較,看是否滿足大小關係要求,如果不滿足就讓他兩個互換,一次至少移動他元素應該在的位置,重複n此,就完成了那個排序工作

  • 特點

  • 優勢:穩定,空間複雜度O(1),屬於就地(原地)排序算法

  • 劣勢:慢,每次只能移動兩個

  • 看下圖我們來了解下冒泡排序的過程
    在這裏插入圖片描述

  • 有序度是一組數據中具有有序元素的個數(比如上面的例子中 5 )

  • 滿有序度:一組完全有序的數據(公式:n*(n-1)/2)

  • 逆序度是冒泡排序是需要交換元素的次數(等於滿有序度-有序度)

冒泡排序代碼實現1

/**
 -  冒泡排序
 - 冒泡排序只會操作相鄰的兩個數據。每次冒泡操作都會對相鄰的兩個元素進行比較,看是否滿足大小關係要求。
 - 如果不滿足就讓它倆互換。一次冒泡會讓至少一個元素移動到它應該在的位置,重複n 次,
 - 就完成了 n 個數據的排序工作。
 **/
public class BubbleSort {
    public void bubbleSort(Integer[] arr, int n) {
        if (n <= 1) return;       //如果只有一個元素就不用排序了
 
        for (int i = 0; i < n; ++i) {
            // 提前退出冒泡循環的標誌位,即一次比較中沒有交換任何元素,這個數組就已經是有序的了
            boolean flag = false;
            for (int j = 0; j < n - i - 1; ++j) {        //此處你可能會疑問的j<n-i-1,因爲冒泡是把每輪循環中較大的數飄到後面,
                // 數組下標又是從0開始的,i下標後面已經排序的個數就得多減1,總結就是i增多少,j的循環位置減多少
                if (arr[j] > arr[j + 1]) {        //即這兩個相鄰的數是逆序的,交換
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = true;
                }
            }
            if (!flag) break;//沒有數據交換,數組已經有序,退出排序
        }
    }
 
    public static void main(String[] args) {
        Integer arr[] = {2, 4, 7, 6, 8, 5, 9};
        SortUtil.show(arr);
        BubbleSort bubbleSort = new BubbleSort();
        bubbleSort.bubbleSort(arr, arr.length);
        SortUtil.show(arr);
    }
}

可能大家對上面for (int j = 0; j < n - i - 1; ++j)的這句有點不理解,我幫助大家解釋分析下

  • for (int j = 0; j < n - i - 1; ++j) 爲什麼需要 -1
    • 因爲倒數第一個元素如果比倒數倒數第二個元素大,就已經執行了數據交換
  • for (int j = 0; j < n - i - 1; ++j) 爲什麼需要 -i,執行下面代碼
  public static int[] bubbleSort(int[] a){
      if (a.length<=1)return a;
      for (int i = 0; i <a.length-1 ; i++) {
          if (a[i]>a[i+1]){
              int t=a[i];
              a[i]=a[i+1];
              a[i+1]=t;
          }
      }
      return a;
  }
  • 大家多次執行上面代碼之後就會發現,每次最大排序後,第一次最大的數在最後面,第二次第二大的數在倒數第二個位置,這次每次循環下來,是不是數據大的是不是默認排序到後面了,所以這裏
    -i

冒泡排序代碼實現2

 public static int[] bubbleSort2(int[] arr) {
       System.out.println(arr.length);
       if (arr.length <= 1) return arr;//已經有序
       for (int i = 0; i < arr.length; i++) {
           for (int j = i + 1; j < arr.length; j++) {
               if (arr[i] > arr[j]) {
                   int a = arr[i];
                   arr[i] = arr[j];
                   arr[j] = a;
               }
           }
       }
       return arr;
   }

上面這個冒泡算法比較簡單,也沒有什麼需要解釋的,大家看下就行。

大家看看下面的這段代碼:


public static int[] bubbleSort(int[] a) {
     
       if (a.length <= 1) return a;
       for (int i = 0; i < a.length-1; i++) {
           if (a[i] > a[i + 1]) {
               int t = a[i];
               a[i] = a[i + 1];
               a[i + 1] = t;
           }
       }
       return a;
   }

假如我們的a數組是這個值: int arr[] = new int[]{1, 25, 2, 35, 14, 58, 10};
我們執行完bubbleSort(arr)後是怎麼樣的結果呢?
這裏我把答案告訴大家:arr={1,2,25,14,35,10,58}
我爲什麼要這麼提示大家注意一下呢?

  • 有的人肯定知道了,就是:執行玩一次冒泡操作後,最大和最小值,已經在排序後的兩端了。(我自己終結的,是不是期望大家和我一起多多驗證。)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章