【问题标题】:Why no immutable double linked list in Scala collections?为什么 Scala 集合中没有不可变的双链表?
【发布时间】:2011-12-23 22:47:03
【问题描述】:

查看this 问题,提问者对List 中某些元素的第一个和最后一个实例感兴趣,似乎更有效的解决方案是使用可以从列表的末尾。但是,集合 API 中只有一种实现,并且它是可变的。

为什么没有不可变的版本?

【问题讨论】:

  • 在我的脑海中,我想不出任何对双向链表的操作可以避免复制 all 元素(而单链表可以共享尾巴 - 例如 O(1) cons)。对我来说,这听起来非常低效。想一想,我不知道 任何 库具有不可变的双向链表...
  • 在 Haskell 中,您要查找的数据结构是 Data.Sequence(它比双线列表稍微复杂一些,但在保持不变性的同时有许多性能改进)。如果 Scala 没有等效的不可变结构,我会感到惊讶。如果没有,那么让我们与开发人员联系并提出要求。
  • @Dan 我相信 Scala 中的等价物是 Vector

标签: scala collections linked-list immutability


【解决方案1】:

因为每次要进行更改时都必须复制整个列表。使用普通的链表,您至少可以预先添加到列表中,而不必复制所有内容。如果您确实想在每次更改时复制所有内容,则不需要链接列表。您可以只使用不可变数组。

【讨论】:

  • 不需要复制整个列表。请参阅我对下一个答案的评论。
【解决方案2】:

这种结构有很多障碍,但其中一个非常紧迫:双向链表无法持久化。

这背后的逻辑非常简单:从列表中的任何节点,您都可以到达任何其他节点。所以,如果我在这个列表 DL 中添加一个元素 X,并尝试使用 DL 的一部分,我将面临这个矛盾:从指向 X 的节点可以到达部分(DL)中的每个元素,但是,通过双向链表的属性,这意味着从 part(DL) 的任何元素我都可以到达指向 X 的节点。由于 part(DL) 应该是不可变的并且是 DL 的一部分,并且由于 DL 不包括节点指向到 X,那是不可能的。

非持久不可变数据结构可能有一些用途,但它们通常对大多数操作不利,因为每当生成派生时都需要重新创建它们。

现在,创建相互引用的严格对象是一件小事,但这是可以克服的。可以使用名称参数和惰性 val,或者可以像 Scala 的 List 一样:实际创建一个可变集合,然后将其“冻结”为不可变状态(参见 ListBuffer 和它的 toList 方法)。

【讨论】:

  • 您关于“矛盾”的结论是错误的。您无法从列表的元素中获取任何内容,其中“元素”是您添加到列表中的对象。您从列表对象前进和后退(对于持久列表,这些遍历操作将返回一个表示新位置的新列表对象)。一种简单的持久实现是让列表将节点之间的前向和后向链接表示为从节点到其后继者和前驱者的两个(持久)哈希表,其中每个节点包含一个元素。
  • @PerMildner “元素”是指指向元素的节点。我在这方面是正确的。请记住,“持久”意味着您不允许创建新列表,只能创建新节点。
【解决方案3】:

因为创建具有严格不变性的相互(循环)引用数据结构在逻辑上是不可能的。

由于简单的存在排序优先级,您不能创建两个指向彼此的节点,因为在创建另一个节点时至少有一个节点将不存在。

可以通过涉及惰性的技巧(通过突变实现)来获得这种循环,但真正的问题是你为什么首先想要这个东西?

【讨论】:

    【解决方案4】:

    正如其他人所指出的,双链表没有持久的实现。您将需要某种树来接近您想要的特征。

    特别是,您可能想看看 finger trees,它提供了 O(1) 访问前后,摊销 O(1) 插入前后,以及 O (log n) 插入别处。 (这与大多数其他常用的树形成对比,它们在任何地方都有 O(log n) 访问和插入。)

    另见:

    【讨论】:

      【解决方案5】:

      作为对@KimStebel 答案的补充,我想补充一下:
      如果您正在寻找适合促使您提出这个问题的问题的数据结构,那么您可以查看Extreme Cleverness: Functional Data Structures in Scala by @DanielSpiewak

      【讨论】:

        猜你喜欢
        • 2011-05-30
        • 1970-01-01
        • 2012-01-07
        • 1970-01-01
        • 2019-10-12
        • 2017-01-13
        • 1970-01-01
        • 2020-11-30
        • 2015-05-09
        相关资源
        最近更新 更多