我是算法分析和 SML 的新手,并且被以下 SML 函数的平均情况运行时挂断了。我会很感激一些关于我的想法的反馈。
fun app([]) = []
| app(h::t) = [h] @ app(t)
因此,在每次递归之后,我们都会得到一堆单元素列表(和一个无元素列表)。
[1]@[2]@[3]@...@[n]@[]
n
原始列表中的元素数量在哪里,1, 2, 3, ..., n
只是为了说明我们正在谈论的原始列表中的哪些元素。L @ R
花费时间与列表 L 的长度成线性关系。假设A
每个元素 @ 花费的时间是恒定的,我想这就像:
[1,2]@[3]@[4]@...@[n]@[] took 1A
[1,2,3]@[4]@...@[n]@[] took 2A
[1,2,3,4]@...@[n]@[] took 3A
...
[1,2,3,4,...,n]@[] took (n-1)A
[1,2,3,4,...,n] took nA
因此,我认为当时的复发会是这样的:
T(0) = C (if n = 0)
T(n) = T(n-1) + An + B (if n > 0)
WhereC
只是基本情况的最终匹配,app([])
并且B
是 的常数h::t
。关闭递归,我们将得到这个(证明省略):
T(n) = (n²+n)A/2 + Bn + C = (A/2)n² + (A/2)n + Bn + C = Θ(n²)
这是我自己的结论,与提供给我的答案不同,即:
T(0) = B (if n = 0)
T(n) = T(n-1) + A (if n > 0)
封闭式
T(n) = An + B = Θ(n)
这是完全不同的。(Θ(n)与Θ(n²)!)但这不是假设L @ R
需要恒定时间而不是线性时间吗?例如,加法是真的
fun add([]) = 0
| add(h::t) = h + add(t) (* n + ... + 2 + 1 + 0 *)
甚至串联
fun con([]) = []
| con(h::t) = h::con(t) (* n :: ... :: 2 :: 1 :: [] *)
我是误解了L @ R
存在的方式还是我的分析(至少在某种程度上)是正确的?