主要問題
在算法問題中,時常結合到排序,而排序的常數也大大影響到我們整體的效能。
基數排序降低常數
若是一般原始型別的排序,可以透過基數排序 (radix sort)。從排序的範圍來決定是否要劃分 8-bit 一組一組。若範圍介於可容忍的 $[0, v]$,當 $v < n$ 時,直接開 $n$ 個 bucket 的方式更好。因為大多數的複雜度都大於線性 $O(n)$
非負整數基數排序
|
|
浮點數基數排序
|
|
慎選內建排序
內建排序常見的有 qsort, sort, stable_sort,我不推薦使用 qsort,因為它在很久以前找到了一個退化情況 A Killer Adversary for Quicksort - 1995,有些題目的測資會出這種特別案例,導致當年的萌新內心受創。除非只有 C 的情況,否則請避開 qsort。如果算法屬於調整某些元素後,再對整體進行排序,這時候 sort 比 stable_sort 慢很多。當情況非常接近已經排序的時候,就使用 stable_sort。
優先隊列
使用 priority queue 的方法通常有三種 set, priority_queue, heap。
- 功能最多的
set、次少的priority_queue,最少的heap。 - 效能方面則是
heap最快、次著priority_queue、最後set。 - 代碼維護最容易的
set、最差的heap。
之前很排斥使用 priority_queue,原因在於撰寫 operator< 與我的邏輯相反,因此都偏愛使用 set,但是效能被拉出來的時候,又必須退回類似 C 的 make_heap、pop_heap … 的接口。