例如,在OCaml中,当您将项目附加到长度为n的列表时
x@[mylist]
答案 0 :(得分:7)
是的,OCaml中@
的运行时为O(n)
(其中n
是左操作数的长度)。
通常附加到不可变单链表(或不可变的双向链表)的末尾将始终为O(n)
。
答案 1 :(得分:4)
您的代码段与您的问题不符,这表示您对操作员的操作或使用的操作员感到困惑。
@
或List.append运算符连接2个列表,list1 @ list2
占用O(length(list1))时间,而不是尾递归。 rev_append
是尾递归的,但仍然是O(n)。然而,将项添加到列表的常用方法是使用::
构造函数,item :: mylist
需要O(1)时间。
答案 2 :(得分:3)
是的,如上所述,有两个原因必须是O(n):
您必须迭代到单链表的末尾,这需要O(n)
由于对是不可变的,你必须复制第一个列表中的所有对才能追加,这也需要O(n)
一个相关的有趣主题是尾递归与非尾递归的追加方式
答案 3 :(得分:1)
总之,是的。
为了说明,一个简单的(不是尾递归)追加函数可以写成如下:
let rec (@) xs ys =
match xs with
| [] -> ys
| x::xs' -> x::(xs' @ ys)
因此,内部附加(@
)会分解第一个列表(xs
)并使用cons
(::
)运算符来构建结果列表。很容易看出有n个前置步骤(::
),其中n
是第一个列表的长度。