排序(Sorting) 是資料處理常用的演算法,目的是把一群物件,照特定規則排成一列。例如: $$ M = \{4,67,2,13\} $$ 照數字大小,由小到大的規則排序,排序的結果為: $$ S_{value}(M) = [2,4,13,67] $$ 當然這只是一種排序規則,我們可以定義各式各樣的規則,例如: $$ S_{digits}(M) = [4,2,67,13] $$ 是根據數字的位數,由少到多排序,4、2 都是 1 位數,67、13 都是 2 位數。 任何規則都可以用來排序嗎?不行。排序規則要定義出 順序 關係,順序關係是定義在兩個物件上的,$a$,$b$ 兩物件,在一個排序規則 $T$ 中,最多有三種可能: $a$ 在 $b$ 之前 $a$ 與 $b$ 順序相同 $b$ 在 $a$ 之前 也就是說,$T$ 將一個物件對應到一個實數,且對於任意物件 $a$,$b$ $T(a) \lt T(b)$ $T(a) = T(b)$ $T(b) \lt T(a)$ 三種情況中只有一種成立。 透過排序規則 $T$,任兩個物件 $a$,$b$ 可以比較,而得到兩者的順序關係。這種透過比較的方式做排序的演算法,理論上最快的演算法,其運算數量級是 $O(n\log n)$,也就是說,再怎麼做最佳化,再怎麼尋找方法,對於 $n$ 個物件,一般的情況,要做最多 $k \cdot n\log n$ 次規則 $T$ 比較、資料搬移等運算,頂多能把 $k$ 盡量變小。這裡一般的情況是指資料是隨機的,且排序前不具有特定順序。 比較式排序法有非常多種,如 Bubble sort,Insertion sort,Quick sort,Heap sort 等等,可參考[ Wikipedia ]。 排序太常用了,C stdlib 實做了 Quick sort: qsort()。C++ STL 實作的 std::sort(),更是結合了 Insertion sort, Quick sort 和 Heap sort,根據資料的特性切換不同演算法。 就運算量最佳化來說,資料的特性會大大地影響排序演算法的選擇。例如,在某個應用場景,要維護一份名單,名單按照名字的字母順序,由小到大排列。在這個應用,每次會增加或...