Tra*_*xon 67 performance functional-programming scala
我最近开始学习scala,并且我遇到了::(cons)函数,它在一个列表前面.
在"Scala编程"一书中,它指出没有附加函数,因为附加到列表具有性能o(n)而前置函数具有o(1)的性能
有些事情让我觉得这个说法错了.
性能是否依赖于实现?是不是可以简单地使用前向和后向链接实现列表并将第一个和最后一个元素存储在容器中?
我想的第二个问题是,当我有一个列表时,我应该做什么,比如说1,2,3,我想在它的末尾添加4个?
sep*_*p2k 77
关键是x :: somelist不变异somelist,而是创建一个新的列表,其中包含x后跟所有元素somelist.这可以在O(1)时间内完成,因为您只需要设置somelist为x新创建的单链表中的后继.
如果使用双重链接列表,则x还必须将其设置为somelist头部的前身,这将进行修改somelist.因此,如果我们希望能够::在不修改原始列表的情况下在O(1)中执行,我们只能使用单链接列表.
关于第二个问题:您可以使用:::将单个元素列表连接到列表的末尾.这是O(n)操作.
List(1,2,3) ::: List(4)
Run Code Online (Sandbox Code Playgroud)
Chr*_*way 19
其他答案对这一现象给出了很好的解释.如果要将多个项目附加到子例程中的列表中,或者如果要通过附加元素创建列表,则功能习惯用法是以相反的顺序构建列表,同时列出列表前面的项目,然后最后扭转它.这给你O(n)性能而不是O(n²).
ska*_*alb 12
前置更快,因为它只需要两个操作:
追加需要更多操作,因为您必须遍历到列表的末尾,因为您只有指向头部的指针.
我以前从未在Scala中编程,但您可以尝试使用List Buffer
大多数功能语言突出显示一个单链表数据结构,因为它是一种方便的不可变集合类型。用功能语言说“列表”时,通常就是您的意思(单链接列表,通常是不可变的)。对于这种类型,append为O(n),而cons为O(1)。