如何使用常量追加和随机访问时间实现不可变集合?

时间:2014-07-08 12:36:30

标签: java c# data-structures collections time-complexity

我正在寻找像this one proposed by Eric Lippert这样的解决方案。这是一个很棒的实现,因为它是不可变的加上附加时间是O(1),但它的缺点是O(i)随机访问时间。

在另一边there is a great implementation of collection上附加O(1)附加和随机访问。唯一的问题是它强烈依赖于可变性。

我的问题是如何实现一个结合两种解决方案优势的集合?那就是:

  1. 不变性
  2. O(1)追加时间
  3. O(1)随机访问时间
  4. 内存复杂性对我来说不是一个大问题。

3 个答案:

答案 0 :(得分:4)

我不知道如何实现一个满足您所有要求的列表 - 不变性,持久性,O(1)插入,O(1)删除,O(1)随机访问。

我的建议是(1)如果您对这个主题感兴趣,请阅读Chris Okasaki的书。 (或者,获得他的论文的副本,这是本书的基础。)和(2)Chris Okasaki建议这里描述的数据结构用于您的目的:

http://www.codeproject.com/Articles/9680/Persistent-Data-Structures#RandomAccessLists

此列表是O(1)插入和O(1)删除头部和O(lg)随机访问。

答案 1 :(得分:1)

除非你包含其他数据结构,否则我不确定如何获得O(1)追加和O(1)随机访问。

通常情况下,如果您希望能够追加元素,则可以复制源集合,这样可以O(1)随机访问,但会O(n)追加;或者你可以做埃里克所做的事情,并保留旧的列表段,这会给你O(1)追加时间,但O(n)随机访问。假设持续的附加时间至关重要,那么您可以选择合并第二个数据结构来提供恒定时间随机访问。

Scala documentation声明"有效地不变"添加和查找其不可变HashMap的时间。如果是的话,我建议看一下它们的实现。您可以采用像Eric这样的解决方案,并为元素本身添加一个有效的不可变索引映射。但是,这会增加一些内存开销,虽然追加操作会很有效,但插入不会。

但是,我对Scala HashMap的性能声明有点怀疑。 Other immutable map实现声明log32(n)复杂性,这可能适用于添加和查找操作。我的直觉告诉我,你不会比对数复杂度更好,尽管log32(n)非常合理。

答案 2 :(得分:-1)

        var bag = new HashBag<int>
                  {
                      1,
                      2,
                      3
                  };
        var g = new GuardedCollection<int>(bag);
        bag.Add(4);
        g.Add(5);

HashBag仍然是可变的,但您仍然可以将其作为不可变的GuardedCollection传递给另一个消费者。