我有一个merge
函数需要时间O(log n)
将两棵树合并为一个,以及listToTree
函数将元素的初始列表转换为单例树并重复调用{{ 1}}在每一对连续的树上,直到只剩下一棵树。
功能签名和相关实现如下:
merge
这是Chris Okasaki在Purely Functional Data Structures中的练习3.3的略微简化版本。
根据练习,我现在将表明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
花费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
我无法再进行此分析。任何人都可以给我一个正确方向的暗示吗?
答案 0 :(得分:6)
几乎就在那里。你已经知道表达式是
所以唯一的问题是评估这笔钱。使用log(AB)= log A + log B和log 2 N = N我们有
With help of calculators,我们可以发现X = O(2 m )= O(n),这是预期的。
(如果您想自己计算,请搜索“几何系列”,或使用积分近似求和。)