Scala中的递归集合,例如List

时间:2014-01-31 09:05:28

标签: scala collections recursive-datastructures

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

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

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

2 个答案:

答案 0 :(得分:7)

主要不可变集合的方法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

TreeSet中/ TreeMap的

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

答案 1 :(得分:1)

  • 对于不可变集合,Vector具有常量size操作
  • 可变Array有一个size操作
  • 对于可变集合,ListBufferArrayBuffer都有size次操作。