实现不可变的,可增长的向量

时间:2012-09-26 14:20:06

标签: data-structures f# clojure functional-programming

我有兴趣在F#中实现持久化(例如纯函数,不可变等),可扩展的向量,以便它们可以在.NET框架中使用。我当前的实现是Hash-Mapped Trie的一个变体,根据Clojure's implementation完成。

我无法使用此实现实现随机访问插入和删除(在随机索引处插入和删除元素)。是否有一些算法/修改可以有效地进行这些操作,或者我可以看一些其他实现?

澄清:当我说'插入'和'删除'时,我的意思是,例如,给定列表[1; 2; 3; 4] 500的位置1会给我[1:500:2:3:4]。我的意思不是setassociate

4 个答案:

答案 0 :(得分:3)

Finger trees可能就是你要找的东西。有一个Clojure implementation可用。

答案 1 :(得分:1)

不可变向量/列表通常仅通过允许一端插入然后在另一端共享不可变数据来提供快速更新。如果你想进行非头/尾插入,那么你真正想做的就是改变集合的不可变端。你必须在你要插入的项目周围分割矢量,然后将它拼接回来创建一个新的矢量,你能够做到的最好的是 O(n)< / em>时间。

不可变排序树的工作方式略有不同,但它们不会让你在 O(n)时间内重新编号指标(键)。

基本上,如果有人发现了一种在不可变向量中支持随机访问插入的有效方法,那么它将在一种主流函数语言中得到支持 - 但是没有这样的已知数据结构或算法,所以没有这样的实施

答案 2 :(得分:1)

唯一能做的就是拆分和加入。这对clojure载体非常无效。这就是为什么Phill Bagwell实现了一个可以拆分并加入log(n)的持久向量。

您可能需要查看此视频:http://blip.tv/clojure/phill-bagwell-striving-to-make-things-simple-and-fast-5936145

或直接发表在他的论文:infoscience.epfl.ch/record/169879/files/RMTrees.pdf

答案 3 :(得分:0)

移植Haskell HAMT libraryInsert operation O(log n)