类似于数组的不可变(持久)数据结构实现,具有快速索引,追加,前置,迭代


11

我正在寻找类似于数组(但不可变)的持久性数据结构,以允许快速索引,追加,前置和迭代(良好的局部性)操作。

Clojure提供了持久的Vector,但仅用于快速追加。Scala的Vector具有有效的固定时间追加和前置,但我无法实现,因为它基于与Clojure向量相同的数据结构(位映射向量trie),并且据我所知,位映射向量trie没有一些技巧就无法快速上手。

我对不是准备使用实现感兴趣,而对自己如何实现这种数据结构的描述感兴趣。

Answers:


13

最明显的候选者是持久性平衡二叉树。您列出的所有操作都可以使用路径复制在或时间内执行。有关如何实现此运行时的更多详细信息,请参阅下面引用的Chris Okasaki的书或此处的答案Ø1个Ølgñ

当然,作为一种变体,这样一棵树的每个叶子本身可以包含一个不可变的数组(连续值的序列)。这会使更新值的效率降低,但是,如果您从不打算修改现有值,只需追加和前置,就可以很好地适应您的情况。这样,您的向量就表示为不可变序列的序列,表示为叶子中具有不可变数组的平衡二叉树。这样可以实现快速索引(叶数为对数),快速追加和前置以及快速迭代。最坏情况下的渐进复杂度并没有改善,但实际上性能可能会明显改善。

标准参考是Chris Okasaki的1998年著作“纯函数数据结构”。
也可以看看


谢谢。看起来RRB树是很好的候选者,并且它们已经具有(不是完整的)Clojure实现。
Tvaroh 2014年

我猜Okasaki告诉我们如何在不变性和持久性下获得这些运行时?
拉斐尔

1
@Raphael,是的。我添加了参考资料,以说明如何实现运行时(到我的答案的开头)。
DW

4

我在有关增量正则表达式匹配的文章中描述了这种数据结构的一种实现-请参见http://jkff.info/articles/ire/#ropes-strings-with-fast-concatenation以及该节上下的文字。

它是各种高度恒定的树(例如B树或2-3树)。基本上是一棵(2,3)树,其叶子是(N,2N-1)个数组,以避免每个元素的开销。(一个(N,2N-1)数组是一个长度在N..2N-1范围内的数组。)N越大,开销越小,但线性增加了拆分和级联的复杂性。索引,拆分和连接之类的操作与它们在2-3棵树中的工作方式非常相似,在叶级别上一般化为(N,2N-1)。


链接断开;请提供适当,可靠的参考(允许人们在没有链接的情况下找到您的论文)。
拉斐尔

我没有在任何期刊上发表论文,仅在我的个人网站上发表。应该把它放到Arxiv上,好主意。
jkff 2014年

我主要考虑的是作者,职称和年份-如果需要的话,可以使Google搜索更加轻松。放到arXiv上会更好,更真实!
拉斐尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.