1. 選擇排序(Selection Sort)
算法思想與理論推導
-
基本思想:
每次從待排序數組中選擇最小(或最大)的元素,將它與當前序列的起始位置交換,逐步將整個數組排序。 -
推導過程:
設數組長度為 n,第一次遍歷需要掃描 n 個元素找到最小值,第二次掃描 (n-1) 個元素……直到最后一個元素。
總的比較次數約為:
算法步驟
-
對于下標 i 從 0 到 n-2:
-
在區間 [i, n-1] 內找到最小元素的下標 min_index。
-
若 min_index ≠ i,則交換元素 arr[i] 與 arr[min_index]。
-
時間復雜度分析
-
最壞情況: O(n2)
-
平均情況: O(n2)
-
空間復雜度: O(1)(原地排序)
-
穩定性: 不穩定(因為交換可能改變相同元素的相對順序)
2. 插入排序(Insertion Sort)
算法思想與理論推導
-
基本思想:
將數組分為已排序和未排序兩部分,每次取未排序部分的第一個元素,在已排序部分中找到合適的位置插入,使已排序部分始終保持有序。 -
推導過程:
對于每個元素,最壞情況下需要和前面所有元素比較并移動位置。第 i 個元素可能需要 i 次比較和移動,總的操作次數約為:當數組已經接近有序時,比較次數大大減少,時間復雜度可以達到 O(n)。
算法步驟
-
從數組第二個元素開始(下標 1):
-
記當前元素為 key,從已排序部分從后向前比較,若遇到比 key 大的元素則后移。
-
插入 key 到合適的位置。
-
時間復雜度分析
-
最壞情況: O(n2)(例如數組逆序排列)
-
平均情況: O(n2)
-
最好情況: O(n)(例如數組已經有序)
-
空間復雜度: O(1)
-
穩定性: 穩定
3. 冒泡排序(Bubble Sort)
算法思想與理論推導
-
基本思想:
通過多次遍歷數組,每次比較相鄰元素,如果順序錯誤則交換,將較大(或較小)的元素逐步“冒泡”到數組的一端。 -
推導過程:
每次遍歷最多做 n-1 次比較,整個排序需要進行 n-1 次遍歷,所以總的比較次數約為:
算法步驟
-
重復遍歷整個數組,
-
對于每一對相鄰元素,如果前者大于后者則交換。
-
每遍歷完一次后,最大的元素“浮”到數組末尾。
-
-
如果一整趟遍歷沒有發生交換,則排序結束。
時間復雜度分析
-
最壞情況: O(n2)
-
平均情況: O(n2)
-
最好情況: 若增加標志位檢測無交換情況,則最好情況為 O(n)(已經有序)
-
空間復雜度: O(1)
-
穩定性: 穩定
4. 歸并排序(Merge Sort)
算法思想與理論推導
-
基本思想:
利用分治法,將數組遞歸地分解為兩個子序列,分別排序后再將兩個有序子序列合并成一個整體有序序列。 -
推導過程:
設 T(n) 為排序 n 個元素的時間復雜度,則:根據主定理,解得 T(n) = O(n log n)。
算法步驟
-
分解階段:
-
將數組分為兩半。
-
遞歸地對兩半分別進行歸并排序。
-
-
合并階段:
-
合并兩個有序子數組。
-
時間復雜度分析
-
最壞情況: O(n log n)
-
平均情況: O(n log n)
-
最好情況: O(n log n)
-
空間復雜度: O(n)(需要額外的輔助空間用于合并)
-
穩定性: 穩定
5. 自然合并排序(Natural Merge Sort)
算法思想與理論推導
-
基本思想:
利用數據中已存在的自然有序(“天然有序”的子序列或“段”),先將序列分割成若干個自然有序的段,再逐步將這些段兩兩歸并。 -
推導過程:
如果輸入數據已經部分有序,則自然有序的段較長,合并次數減少,最佳情況時間復雜度可接近 O(n)。
最壞情況仍然為歸并排序的情況,即當數據完全無序時,各自然段長度為 1,總共需要 O(log n) 次歸并,每次歸并時間 O(n),故為 O(n log n)。
算法步驟
-
識別自然段:
-
掃描數組,識別連續遞增(或遞減)的一段作為一個“自然段”。
-
-
歸并階段:
-
將相鄰的自然段兩兩合并,形成新的較長的自然段。
-
重復歸并過程直到整個數組有序。
-
時間復雜度分析
-
最壞情況: O(n log n)
-
平均情況: O(n log n)
-
最好情況: 如果數組整體有序,識別出一個自然段,時間復雜度 O(n)
-
空間復雜度: O(n)(歸并時需要輔助數組)
-
穩定性: 穩定
6. 快速排序(Quick Sort)
算法思想與理論推導
-
基本思想:
利用分治策略選擇一個“基準”(這里取第一個元素),將數組分成兩部分:左邊所有元素均小于基準,右邊所有元素均大于基準,然后對這兩部分遞歸進行排序。 -
推導過程:
設 T(n) 為排序 n 個元素的時間復雜度,則:其中 k 表示劃分后左側子數組的大小。
-
平均情況: 當每次劃分較為均勻(大致各半),有 T(n) = 2T(n/2) + O(n),解得 T(n) = O(n log n)
-
最壞情況: 當劃分極不均勻(如數組已排序,且始終選擇最小或最大元素作為基準),有 T(n) = T(n-1) + O(n),解得 T(n) = O(n2)。
-
算法步驟
-
選擇基準:
-
選擇第一個元素作為基準。
-
-
分區操作:
-
從數組兩端向中間掃描,將比基準小的元素移到左邊,比基準大的元素移到右邊。
-
-
遞歸排序:
-
對左右兩個子數組分別進行快速排序。
-
時間復雜度分析
-
最壞情況: O(n2)(例如每次劃分極不均勻)
-
平均情況: O(n log n)
-
最好情況: O(n log n)
-
空間復雜度: O(log n)(遞歸調用棧空間,平均情況下)
-
穩定性: 不穩定
算法對比
算法 | 時間復雜度(最壞/平均/最好) | 空間復雜度 | 穩定性 | 特點與適用場景 |
---|---|---|---|---|
選擇排序 | O(n2) / O(n2) / O(n2) | O(1) | 不穩定 | 實現簡單,但比較次數固定,不適合大規模數據排序 |
插入排序 | O(n2) / O(n2) / O(n) | O(1) | 穩定 | 對部分有序數據效果好,適用于小規模數據或在線排序 |
冒泡排序 | O(n2) / O(n2) / O(n)(優化版) | O(1) | 穩定 | 實現簡單,但效率低,更多用于教學演示 |
歸并排序 | O(n log n) / O(n log n) / O(n log n) | O(n) | 穩定 | 時間復雜度穩定,適用于大規模數據,但需要額外空間 |
自然合并排序 | O(n log n) / O(n log n) / O(n) | O(n) | 穩定 | 能利用已有有序序列提升效率,適合部分有序數據 |
快速排序 | O(n2) / O(n log n) / O(n log n) | O(log n)(平均) | 不穩定 | 平均性能優異,原地排序,適合大規模數據,但最壞情況需注意 |
總結
-
簡單排序(選擇、插入、冒泡):
這些算法實現簡單,但時間復雜度均為 O(n2)(在最壞或平均情況下),適合數據量較小的情況。插入排序在數據部分有序時表現較好,而冒泡排序常用作教學示例。 -
分治排序(歸并、快速、自然合并):
歸并排序和快速排序均有 O(n log n) 的平均時間復雜度,其中歸并排序穩定但需要額外空間,而快速排序在原地排序方面有優勢。自然合并排序則利用了數據中已有的有序性,在實際應用中對于部分有序數據可獲得較好性能。