在scala中以固定时间连接列表?

问题描述

| 在Scala中,是否有内置函数或外部库可用于在恒定时间内连接两个列表(或数组,向量,列表缓冲区等)?这样的操作可能会破坏/变异两个原始列表。据我所知,我看到的所有用于连接列表的功能都是线性运行的。 非常感谢。     

解决方法

        有一个具有
concat
方法的
UnrolledBuffer
接受了另一个
UnrolledBuffer
并在
O(1)
中返回它们的串联。它对参数缓冲区具有破坏性-调用此方法后,第二个缓冲区将为空。     ,        功能语言中解决常数时间追加的经典方法(至少回到Hughes '84)是通过“差异列表”来实现的,其中追加到列表的编码为函数组成。 这是Haskell的草图:
newtype DList a = DL { unDL :: [a] -> [a] }
因此DList是一个从列表到列表的函数。一些介绍形式:
-- The empty list is the identity function
empty       = DL id    

-- Singletons are the compositions of the cons function
singleton   = DL . (:)

-- Appending two lists is just composition
append xs ys = DL (unDL xs . unDL ys)
完整的实现是关于Hackage的,对于翻译成Scala来说应该很简单。     ,        我当时以为ѭ6可以提供固定时间的追加,因为您可以将一个列表的末尾加入另一个列表的开头,而不必遍历任何一个。 但是,
scala.collections.mutable.DoubleLinkedList
或ѭ8neither都不能这样工作。 原因可能是
a.append(b)
会同时修改a和b,这是意外的。     ,        这是一个支持恒定时间串联的简单不变数据结构。它只是表明有可能,但并不旨在实际使用。用于检索元素的“ 10”实现运行时非常糟糕,可以通过使用迭代器遍历树来轻松地进行改进。 我想知道是否有更好的数据结构?
sealed abstract class Tree[+T] {
  def items: List[T]
  def append[U >: T](v: U): Tree[U] = this append Leave(v)
  def append[U >: T](other: Tree[U]) = Node(this,other)
}

case class Node[+T](val left: Tree[T],val right: Tree[T]) extends Tree[T] {
  def items = left.items ++ right.items
}

case class Leave[+T](val value: T) extends Tree[T] {
  def items = List(value)
}

case object EmptyTree extends Tree[Nothing] {
  def items = Nil
}

object ConstantTimeConcatenation {
  def main(args: Array[String]) {
    val first = EmptyTree append 1 append 2 append 3
    val second = EmptyTree append 4 append 5
    val both = first append second // runs in linear time
    println(both.items)
  }
}