当我们执行l1 @ l2
时,它是O(length(l1))
,因为我们必须通过l1并连接l1和l2。
所以我的问题是为什么实现不会保持last_element
指针?
我问这个是因为我想学习/理解OCaml
标准库实现的决策过程。
答案 0 :(得分:5)
转到l1
的最后一个元素对我们没有帮助。我们需要复制l1
的全部内容,如果不经过它我们就无法做到。因此,指向l1
末尾的指针对我们没有帮助。
答案 1 :(得分:5)
以sepp2k的答案为基础: 列表以这种方式在OCaml中实现。
type 'a list = Nil | Cons of 'a * 'a list
列表l1 [1; 2; 3]可以这样想:
Cons (1, Cons(2, Cons(3, Nil)))
假设你想用l2连接它,在Cons(3,Nil)中,你需要用l2替换Nil,这是不可能的,因为这些元素是不可变的。新列表以这种方式构建:
Cons (1, Cons(2, Cons(3, l2)))
是O(长度(l1))
答案 2 :(得分:2)
Octref和sepp2k解释了为什么O(1)
无法附加缺点列表。我只想指出,您可以始终使用支持常量时间(摊销或最坏情况)附加的其他数据结构。
其他选项包括:
1)差异列表,O(1)
附加,但需要O(n)
才能将其变为缺点列表。 (但不知道OCaml中的任何实现)
2)Catenable列表有O(1)
个摊销附加。
3)您始终可以使用可变链接列表。例如电池中的DllList
。