[英]What Time Complexity Does Haskell's “tail”-Function Have?
當我想到自己時,我正在閱讀關於Haskell的教程; Haskell的tail
函數具有什么時間復雜度(以及為什么)? (我在任何文檔中都找不到答案)
我猜想對於大小為n的列表, tail
函數將是O(n) ,即只是將尾部復制到新列表並返回該列表。 但話說回來,我不太了解Haskell的底層架構(我是語言的新手)。
當然,我可以計時。 但我還不知道如何在Haskell中計算時間,我也想了解Haskell如何處理問題,證明為什么它是O(n)/ O(1)或其他什么。
提前致謝 :)
Haskell語言沒有指定。 但在GHC(最常用的實現)中,它是O(1)。 尾部不需要復制 - 在原始列表和只使用列表尾部的人之間共享是安全的 - 因為Haskell中的所有內容都是不可變的。
挑戰問題:為什么除了列表的最后一個元素之外的所有init
都在O(n)中運行? 為什么上面的共享參數不適用於那里?
簡短回答:如果列表已構建到該節點,則為O(1) 。
Haskell中的列表是一個鏈表 。 它被定義為:
data [a] = [] | a : [a]
這意味着要么我們有空列表,要么是a : [a]
構造。 因此,具有head
( a
)的節點引用類型a
的對象, tail
引用列表[a]
(可以是空列表或另一個節點)。
base
tail
的源代碼定義為:
tail :: [a] -> [a] tail (_:xs) = xs tail [] = errorEmptyList "tail"
它在O(1)中運行,因為我們只需按指向該節點的“尾部”。
但請注意Haskell懶惰地工作 。 這不是因為我們得到一個類型為[a]
的對象,我們有一個物化列表:通常Haskell首先必須評估它已經放棄給定節點的表達式樹 。 這可能導致評估復雜且耗時的算法。 所以它取決於你給出的表達式樹 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.