【发布时间】:2010-04-11 13:56:34
【问题描述】:
我有一个 merge 函数,它需要时间 O(log n) 将两棵树组合成一棵树,还有一个 listToTree 函数,它将初始元素列表转换为单例树,并在每对连续的树上重复调用 merge直到只剩下一棵树。
函数签名及相关实现如下:
merge :: Tree a -> Tree a -> Tree a --// O(log n) where n is size of input trees
singleton :: a -> Tree a --// O(1)
empty :: Tree a --// O(1)
listToTree :: [a] -> Tree a --// Supposedly O(n)
listToTree = listToTreeR . (map singleton)
listToTreeR :: [Tree a] -> Tree a
listToTreeR [] = empty
listToTreeR (x:[]) = x
listToTreeR xs = listToTreeR (mergePairs xs)
mergePairs :: [Tree a] -> [Tree a]
mergePairs [] = []
mergePairs (x:[]) = [x]
mergePairs (x:y:xs) = merge x y : mergePairs xs
这是 Chris Okasaki 的纯函数式数据结构中练习 3.3 的略微简化版本。
根据练习,我现在将证明listToTree 需要O(n) 时间。我不能。 :-(
ceil(log n) 对listToTreeR 的递归调用很简单,这意味着ceil(log n) 对mergePairs 的调用。
mergePairs 的运行时间取决于列表的长度和树的大小。列表的长度是2^h-1,树的大小是log(n/(2^h)),其中h=log n是第一个递归步骤,h=1是最后一个递归步骤。因此,每次调用mergePairs 都需要时间(2^h-1) * log(n/(2^h))
我无法进一步进行此分析。谁能给我一个正确方向的提示?
【问题讨论】:
标签: haskell time complexity-theory big-o