使用有效差异搜索树来导出树

时间:2016-02-19 03:50:18

标签: haskell data-structures

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

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

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

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

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

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

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