簡體   English   中英

Haskell中sortBy的復雜性

[英]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 2O(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)

是一個不一致的比較,對於兩個列表ab (比如[30,10][25,15] ),你可以得到

cmp a b == cmp b a = LT

我不確定你的算法總是有效。

在查看sortBy的實現並在我的腦海中sortBy跟蹤排序之后,我認為對於給定的目的,它起作用(如果列表元素是不同的)並且不一致的比較沒有壞處。 對於某些排序算法,不一致的比較可能導致排序循環,但對於合並排序變體,不應該發生。

一步一步好

  1. chunksOf 2必須遍歷整個列表,所以O(n)和我們列表長度的一半。 但是,由於常數倍數不會影響復雜性,我們可以忽略它。
  2. map (sortBy...遍歷整個列表O(n)執行常量時間操作* O(1) = O(1*n) = O(n)
  3. sortBy與常數時間比較*是O( n * log n)
  4. concatO(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM