排序演算法原理總結和Python實現

星塵 StarDust發表於2021-01-01

1 排序演算法分類

比較類排序:通過比較來決定元素間的相對次序,由於其時間複雜度不能突破O(nlogn),因此也稱為非線性時間比較類排序。
非比較類排序:不通過比較來決定元素間的相對次序,它可以突破基於比較排序的時間下界,以線性時間執行,因此也稱為線性時間非比較類排序。
在這裡插入圖片描述

相關概念:

穩定:如果a原本在b前面,而a=b,排序之後a仍然在b的前面。
不穩定:如果a原本在b的前面,而a=b,排序之後 a 可能會出現在 b 的後面。
時間複雜度:對排序資料的總的操作次數。反映當n變化時,操作次數呈現什麼規律。
空間複雜度:是指演算法在計算機內執行時所需儲存空間的度量,它也是資料規模n的函式。

排序演算法原理和Python實現:

氣泡排序(Bubble Sort) – 初級排序演算法
選擇排序(Selection Sort)-- 初級排序演算法
插入排序(Insertion-Sort)-- 初級排序演算法

快速排序(Quick Sort)-- 高階排序演算法
歸併排序(Merge Sort)-- 高階排序演算法
堆排序(Heapsort)-- 高階排序演算法
希爾排序(Shell Sort)-- 高階排序演算法

計數排序(Counting Sort)-- 特殊排序演算法
桶排序(Bucket sort) – 特殊排序演算法
基數排序(Radix Sort)-- 特殊排序演算法

2 演算法複雜度

在這裡插入圖片描述

3 排序演算法的穩定性

穩定排序是指原來相等的兩個元素前後相對位置在排序後依然不變。
不穩定演算法:快選堆希(快速排序、選擇排序、堆排序、希爾排序)
1、選擇排序

選擇排序是給每個位置選擇當前元素最小的,比如給第一個位置選擇最小的,在剩餘元素裡面給第二個元素選擇第二小的,依次類推,直到第n - 1個元素,第n個元素不用選擇了,因為只剩下它一個最大的元素了。那麼,在一趟選擇,如果當前元素比一個元素小,而該小的元素又出現在一個和當前元素相等的元素後面,那麼交換後穩定性就被破壞了。比較拗口,舉個例子,序列5 8 5 2 9,我們知道第一遍選擇第1個元素5會和2交換,那麼原序列中2個5的相對前後順序就被破壞了,所以選擇排序不是一個穩定的排序演算法。

2、快速排序

快排的核心思想就是每次我選取一個基準,將小於這個基準的元素劃分到左邊,大於這個基準的元素劃分到右邊,然後將基準放在這兩塊的中間。快排是不穩定的。看下面這個簡單的例子:
假設,當前的基準 5 ,我們已經成功的把小於 5 的元素劃分到左半部分( 3,3,4,3),大於 5 的元素劃分到了右半部份(8,9,10,11)。
[ 5 3 3 4 3 8 9 10 11 ]
此時我們將基準交換到兩個部分的中間,方法就是將 5 與 左半部分最後一個元素 3 進行交換。到這裡你就會發現,原來在後面的 3 現在跑到其它 3 的前面來了。

3、堆排序

我們知道堆的結構是節點 i 的孩子為 2 * i 和 2 * i + 1 節點,大頂堆要求父節點大於等於其 2 個子節點,小頂堆要求父節點小於等於其 2 個子節點。在一個長為 n 的序列,堆排序的過程是從第 n / 2 開始和其子節點共 3 個值選擇最大(大頂堆)或者最小(小頂堆),這 3 個元素之間的選擇當然不會破壞穩定性。但當為 n / 2 - 1, n / 2 - 2, … 1 這些個父節點選擇元素時,就會破壞穩定性。有可能第 n / 2 個父節點交換把後面一個元素交換過去了,而第 n / 2 - 1個父節點把後面一個相同的元素沒有交換,那麼這 2 個相同的元素之間的穩定性就被破壞了。所以,堆排序不是穩定的排序演算法

4、希爾排序

希爾排序是按照不同步長對元素進行插入排序,一次插入排序是穩定的,不會改變相同元素的相對順序。但在不同的插入排序過程中,相同的元素可能在各自的插入排序中移動,最後其穩定性就會被打亂,所以希爾排序是不穩定的。

參考資料

十大經典排序演算法(動圖演示)
氣泡排序(Bubble Sort)
選擇排序(Selection Sort)
插入排序(Insertion-Sort)
快速排序(Quick Sort)
歸併排序(Merge Sort)
堆排序(Heapsort)
希爾排序(Shell Sort)
計數排序(Counting Sort)
桶排序(Bucket sort)
基數排序(Radix Sort)

相關文章