個人筆記之交換排序

交換排序:

  • 包括冒泡排序和快速排序

冒泡排序

算法思想java

  • 逐個兩兩比較大小,若前一個元素大於後一個元素則使兩者交換位置。如此往復,完成一趟遍歷便可使得一個元素(最大值)歸位。
效率及穩定性
  • 時間複雜度最好是O(n),最壞是O(n^2),平均爲O(n^2),空間複雜度爲O(1),是一種穩定的排序算法;
  • 就地排序,每趟產生全局有序區;
適用場景:
  • 適用元素較少的狀況下,元素太多的話,交換和比較次數都會不少,影響效率,元素多的狀況適合用快速排序.
  • 當數組基本有序的狀況下適合使用冒泡排序和直接插入排序,它們在基本有序的狀況下排序的時間複雜度接近O(n)
示例代碼:

private static void Sort(int[] a) {
    boolean tag;//用於判斷實時的數組是否已經有序
    for (int i = 0; i < a.length - 1; i++) {
    //總共須要a.length-1趟排序,由於每趟只歸位一個元素,需將a.length-1個元素歸位便可使整個數組有序
        tag = true;//每趟開始以前將標誌置爲true
        for (int j = 0; j < a.length - 1- i; j++) {
        //第i趟只須要比較a.length-i-1次,如:第一趟只須要比較a.length-1次
            if (a[j] > a[j + 1]) {
                int temp = 0;
                temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
                tag = false;//發生交換就將標誌位置爲false,表示當前數組尚未徹底有序;
            }
        }
        if (tag) {//進行一趟完整的排序後沒有發生交換則說明已經排序完成;
            return;//結束排序
        }
    }
}複製代碼

快速排序

算法思想
  • 在要排的數(好比數組A)中選擇一箇中心值key(好比A[0]),經過一趟排序將數組A分紅兩部分,其中以key爲中心,key右邊都比key大,key左邊的都key小,而後對這兩部分分別重複這個過程,直到整個有序。 整個快排的過程就簡化爲了一趟排序的過程,而後遞歸調用就好了。

效率及穩定性:
算法

  • 快速排序的最好狀況下的時間複雜度爲O(N*log2N),最壞狀況下的時間複雜度爲O(N^2),平均的時間複雜度爲O(N*log2N)。空間複雜度爲O(1),屬於不穩定排序。
  • 每趟歸位一個元素;
適用場景:
  • 快速排序適用於數據雜亂無章的場景,並且越亂,快速排序的效率越體現的淋漓盡致。
  • 實現步驟以下:
  1. 遞歸出口,條件爲(low>high)
  2. 給指針i、j和基準值key賦值
  3. 完成一趟排序,循環條件爲(i != j)
  4. 循環內部,
    1. 從右往左找小於等於key的值下標 j,條件爲(a[j]>key)
    2. 從左往右找大於key的值下標 i,條件爲(a[i]<=key&& i<j)
    3. 交換a[i]和a[j]的值
  5. 完成一趟循環以後,交換key和a[i]的位置
  6. 開始遞歸:
    1. 對key左邊的數進行排序
    2. 對key右邊的數進行排序
示例代碼:
public static void quickSort(int[] a) {
    if (a.length > 0) {
        quickSort(a, 0, a.length - 1);
    }
}

//核心遞歸體
private static void quickSort(int[] a, int low, int high) {
    //遞歸出口
    if (low > high) {
        return;
    }
    int i = low;
    int j = high;
    int key = a[low]; //基準元素取第一個元素,取其餘的直接改就行,2八、29行也要改
    //完成一趟排序
    while (i != j) {//每當ij相等時跳出外層循環,每完成一趟遍歷ij都是相等的;
        while (a[j] > key) {//從右往左找到第一個小於等於key的數
            j--;
        }
        while (a[i] <= key && i < j) {//從左往右找到第一個大於key的數,等於時也繼續,i<j保證i不可能大於j
            i++;
        }
        //交換兩數字位置
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    //調整key的位置,將key的位置與ij相遇的位置交換
    int temp = a[i];
    a[i] = a[low];
    a[low] = temp;

    //對key左邊的數進行排序
    quickSort(a, low, i - 1);
    //對key右邊的數進行排序
    quickSort(a, i + 1, high);
}
複製代碼
相關文章
相關標籤/搜索