【问题标题】:Search tree with efficient diff for derived trees对派生树具有有效差异的搜索树
【发布时间】:2016-05-31 12:49:40
【问题描述】:

我正在寻找 Haskell 中的搜索树实现,它为共享结构的树提供有效的差异函数。例如,如果我有一棵大树 x(例如,有数百万个元素),我在其中插入三个新元素以生成 x',我希望能够调用 difference x x' 来取回这些元素, 其中difference 的实现方式是通过仅访问两棵树之间不共享的节点来找到感兴趣的元素。

我想到的场景就像一个版本控制系统,每个新版本都是从前一个版本派生的,我们可能需要找出任意两个版本之间的差异。

数据结构还应支持高效的插入、删除和查找操作(例如 O(log n))。

这样的实现将依赖诸如 System.Mem.StableName 或 Data.Unique.Id 之类的东西来唯一地标记树中的每个节点,从而允许 difference 函数有效地识别共享结构并避免下降到它。

这样的东西已经存在了吗?如果没有,实施它的好策略是什么?我正在考虑修改诸如吴兴波的 RBTree 实现之类的东西,为每个节点添加唯一标签,但我对其他选项持开放态度。

【问题讨论】:

  • 除了difference 函数之外,你还需要树的哪些属性?您还需要快速插入吗?会员测试?元素的类型是什么?这些是来自任意类型,还是树独有的不透明键类型?
  • 是的,我需要快速插入、删除和查找(例如 O(log n))。在我的例子中,元素类型是特定于应用程序的记录类型,以ByteStrings 为键(即我会将其用作Map,而不仅仅是Set),但理想情况下这适用于任何键类型这是Ord 的一个实例。
  • 一般Ord 键可以降低效率,与更结构化的键相比。在您的情况下尤其如此,因为两棵等效的树可能会以不同的方式平衡。我想尝试、PATRICIA 树等可以提供更好的差异性能。

标签: haskell data-structures


【解决方案1】:

如果您想知道一棵大树x 的区别,那么 您可以显式跟踪更改,而不是计算差异:

-- extend a map with some insertions and deletions
data ExtMap k v = ExtMap { baseMap :: Map k v, changes :: Map k (Maybe v) }

fromMap :: Map k v -> ExtMap k v
fromMap x = ExtMap x Map.empty

toMap :: Ord k => ExtMap k v -> Map k v
toMap (ExtMap x y) = Map.mergeWithKey (\_ _ u -> u) id id x y

lookup :: Ord k => k -> ExtMap k v -> Maybe v
lookup k (ExtMap x y) = case Map.lookup k y of
  Just mv -> mv             -- if there is a change for this key, return that
  Nothing -> Map.lookup k x -- otherwise look in the base map

insert :: Ord k => k -> v -> ExtMap k v -> ExtMap k v
insert k v (ExtMap x y) = ExtMap x (Map.insert k (Just v) y)

delete :: Ord k => k -> ExtMap k v -> ExtMap k v
delete k (ExtMap x y) = ExtMap x (Map.insert k Nothing y)

【讨论】:

  • 谢谢,Twan。这适用于我给出的示例,但也许我应该在我的问题中提供更多上下文。我的场景类似于版本控制系统,其中每个新版本都是从前一个版本派生的,我可能需要找到任何两个版本之间的差异。所以我需要比较的不仅仅是一棵大树x,而是很多。我会更新问题以澄清。
【解决方案2】:

我自己继续implemented this,修改吴兴波的RBTree以支持带有版本信息注释的值,然后可以使用diffVersion有效地计算差异。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 2016-12-08
    • 2017-10-01
    • 1970-01-01
    相关资源
    最近更新 更多