[英]Complexity of a sortBy in Haskell
我提出了解決另一個問題的想法 ,並希望能夠幫助確定函數的復雜性,因為我對此並不太了解。 我是否正確地猜測每個塊的“未分類”將是O (n * log 2)
? 然后sortBy函數的復雜性是什么,它將一個塊的最后一個與另一個塊的頭部進行比較? 我的猜測是,該函數只會比較對,而不需要根據總列表找到一個塊的順序。 另外,由於整體功能的懶惰優化,Haskell會提供不同的復雜性嗎? 提前致謝!
import Data.List.Split (chunksOf)
import Data.List (sortBy)
rearrange :: [Int] -> [Int]
rearrange = concat
. sortBy (\a b -> compare (last a) (head b))
. map (sortBy (\a b -> compare b a))
. chunksOf 2
讓我們單獨看一下這些部分(讓n
為list參數的長度):
chunksOf 2
是O(n)
,得到長度(n+1) `quot` 2
。 map (sortBy ...)
:由於傳遞給sortBy ...
所有列表都有長度<= 2
,因此每個排序都是O(1)
,因此整個map
再次為O(n)
。 sortBy (\\ab -> compare (last a) (head b))
:比較總是O(1)
,因為采用last
元素的列表是有界長度( <= 2
),因此整個sortBy
操作是O(n*log n)
concat
再次是O(n)
。 總的來說,我們有O(n*log n)
。
但請注意
cmp = \a b -> compare (last a) (head b)
是一個不一致的比較,對於兩個列表a
和b
(比如[30,10]
和[25,15]
),你可以得到
cmp a b == cmp b a = LT
我不確定你的算法總是有效。
在查看sortBy
的實現並在我的腦海中sortBy
跟蹤排序之后,我認為對於給定的目的,它起作用(如果列表元素是不同的)並且不一致的比較沒有壞處。 對於某些排序算法,不一致的比較可能導致排序循環,但對於合並排序變體,不應該發生。
一步一步好
chunksOf 2
必須遍歷整個列表,所以O(n)
和我們列表長度的一半。 但是,由於常數倍數不會影響復雜性,我們可以忽略它。 map (sortBy...
遍歷整個列表O(n)
執行常量時間操作* O(1)
= O(1*n)
= O(n)
sortBy
與常數時間比較*是O( n * log n)
concat
是O(n)
所以總共O(n + n + n log n + n)
= O ((3 + log n) * n)
= O(n log n)
*由於列表的長度保持為2或更小,我們可以說排序和訪問最后一個元素的操作分別是O(2 * log 2)
和O(2)
,它們都是常量時間, O(1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.