具有高效插入/删除的“列表”

时间:2013-12-18 02:14:48

标签: haskell

我正在寻找在索引i处插入/删除日志(N)的“列表”。我把单词“List”放在引号中,因为我并不是说它是一个真正的Haskell List,而是任何带有一堆对象的有序容器(事实上,它可能需要内部的某种树)。我很惊讶我还没有找到一个很好的解决方案....

这是我迄今为止最好的解决方案 - 使用带有这两个函数的Data.Sequence。

doInsert position value seq = before >< ( value <| after)
     where
     (before, after) = splitAt position seq

doDelete position seq = before >< (drop 1 after)
     where
     (before, after) = splitAt position seq

虽然这些在技术上都是log(N)函数,但感觉就像我为每个插入/删除做了一堆额外的东西....换句话说,这就像K * log(N)的K一样缩放比它应该的大。另外,由于我必须自己定义这些内容,我觉得我正在使用Sequence来实现它不适合的东西。

有更好的方法吗?

这是一个相关的问题(虽然它只处理序列,我很乐意使用其他任何东西):Why doesn't Data.Sequence have `insert' or `insertBy', and how do I efficiently implement them?

是的,这个问题与我几天前发布的另一个问题有关:Massive number of XML edits

2 个答案:

答案 0 :(得分:2)

有一些结构,如catenable seqs,catenable queues等,可以给你O(1)加入。然而,我所知道的所有这些结构都通过给你O(i)分裂而逃脱了。如果你想分割和加入两者尽可能最佳,我认为一个fingertree(aka Sequence)是你最好的选择。 Sequence的结构方式的全部要点是确保分裂,连接等在分裂和连接时有一个渐近但不太可怕的杂耍,等等。

如果你可以逃脱IntMap开始稀疏并变得更密集,并且偶尔会重建&#34;当事情变得过于密集时,可能会给你更好的表现 - 但这实际上取决于你的使用模式。

答案 1 :(得分:0)

如果您仔细使用预定义的Haskell列表,那么它们应该没有问题。 (例如,在连接两个列表时)。

如果您希望找到列表的实现,并且有效插入和删除,AVLTree或任何类型或平衡的二叉树都可以工作。 例如,在AVLTree中存储一个元组(Int,a),其中Int是列表的索引和elem。 因此,就平均复杂性而言,操作将是对数的插入和删除。

我希望这能回答你的问题。