【发布时间】:2017-12-11 16:20:35
【问题描述】:
我有以下数据:
data Item a = { id :: ID
, parentId :: Maybe ID
, data :: a
}
data ItemTree a = ItemTree ID a [ItemTree a]
我想拥有这个功能:buildForest :: [Item a] -> [ItemTree a],它将返回一个非平凡的森林(即尊重父母关系)。我可以假设每个项目的 ID 都是唯一的,并且所有项目都有其父列表,如果这很重要的话。
这几天我一直在努力解决这个问题。我通过改变对象(实际上是它们的副本)在 javascript 中实现了类似的代码,但我很想知道 Haskell 是如何做到这一点的。
到目前为止,我对该主题的最佳想法是:
toRelations :: Item a -> ((ID, ID), Item a)
toRelations it@{id, parentId} = ((parentId, id), it)
所以现在我可以有一个从父母到孩子的关系列表,所以箭头指向正确的方向。我仍然需要从中构造一棵树,同时避免进行缓慢的查找。这有意义吗?
【问题讨论】:
-
我将分两步解决这个问题:首先,通过识别所有从未用作
parentId的IDs 来找到结果林的所有根。获得该列表后,通过扫描输入项以查找当前节点的子节点,从每个根递归地构造树。每个步骤都是 O(n^2) 天真地完成,但可以通过提取适当的数据类型(如Data.Map)来改进到 O(n log n)。 -
哎呀。我对如何处理根的描述实际上是如何找到叶子。稍微后退。至少根更容易找到。即使在幼稚的情况下,也只需 O(n)。
标签: haskell tree functional-programming