主要問題
在算法問題中,時常結合到排序,而排序的常數也大大影響到我們整體的效能。
基數排序降低常數
若是一般原始型別的排序,可以透過基數排序 (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
… 的接口。