【问题标题】:Recursive collections in Scala such as ListScala 中的递归集合,例如 List
【发布时间】:2014-01-31 09:05:28
【问题描述】:

目的是使用不需要迭代或递归计算大小的 Scala 集合。

例如List 被证明是一个递归构造(例如https://stackoverflow.com/a/8197826/3189923),为了获得大小,有必要对其进行迭代;即对列表中的元素数量进行O(N) 操作。

因此要问这个操作是O(1)是哪些集合? 非常感谢。

【问题讨论】:

标签: scala collections recursive-datastructures


【解决方案1】:

主要不可变集合的方法size的成本(根据快速查看代码):

Seq:
  LinearSeq:
    List - O(N)
    Stream - O(N)*
    Queue - O(N) // Implemented using List
    Stack - O(N)* // Implemented using List, with additional complexity
  IndexedSeq:
    Vector - O(1)
    NumericRange - O(1)
    Array - O(1) // WrappedArray, ArrayOps
    String - O(1) // WrappedString, StringOps
    Range - O(1)
Set:
  HashSet - O(1) // HashSet.HashTrieSet
  TreeSet - O(N) // RedBlackTree.count - recursive with stack usage 
  BitSet - O(Max)* // fast enough. O(1) for collections of small ints
  ListSet - O(N)
Map:
  HashMap - O(1) // HashMap.HashTrieMap
  TreeMap - O(N) // RedBlackTree.count - recursive with stack usage
  ListMap - O(N)

来自文档:

为了计算Stream 的长度,首先必须完全实现它,这可能会导致对无限级数的完整评估,假设这就是您的Stream 所代表的内容。

堆栈

Stack#length 复杂度比List#length 复杂度差得多:它创建N 新对象来迭代Stack

位集

BitSet 用于小整数的集合。

BitSet#size 的复杂性取决于最大元素,而不是元素数量。关于O(Max/64)。另见BitSet#size implementation

树集/树图

我不确定TreeSetTreeMap 的复杂性,它看起来像使用堆栈递归(不是尾递归)。见RedBlackTree.count implementation

【讨论】:

    【解决方案2】:
    • 对于不可变集合,Vector 有一个常量 size 操作
    • 可变的Array 有一个常量size 操作
    • 对于可变集合,ListBufferArrayBuffer 都有常量 size 操作。

    【讨论】:

      猜你喜欢
      • 2018-12-15
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      • 2018-07-19
      • 2018-06-29
      • 2015-03-25
      • 1970-01-01
      • 2020-03-24
      相关资源
      最近更新 更多