树到可能路径列表(值)

时间:2016-10-18 11:06:00

标签: haskell

给定定义为

的树数据结构
data Tree = Node Int Tree Tree | Leaf

如何将其转换为沿所有路径的值列表?

例如,Node 1 (Node 2 Leaf Leaf) (Node 3 Leaf Leaf)应转换为[[1,2], [1,3]]

2 个答案:

答案 0 :(得分:4)

你有一个递归数据结构,所以你应该期待一个递归的解决方案。这种解决方案的第一步是确定基本案例。对于这个问题,有明显的基本情况:Leaf。我们可能还希望将Node x Leaf Leaf视为基本情况,以避免重复路径。

现在让我们写下类型签名。这应该清楚我们的基本情况应该产生什么。

paths :: Tree -> [[Int]]

对于Leaf,明智的做法是返回一个包含空列表的列表,因为Leaf表示空路径。

paths Leaf = [[]]

对于Node x Leaf Leaf,我们可以返回一个包含x列表的列表。

paths (Node x Leaf Leaf) = [[x]]

下一部分需要最多的考虑。我们需要考虑如何处理非基本情况Node x left right。这里的策略是假设我们得到paths leftpaths right的结果,然后决定我们需要对x做什么。我们正在构建路径,因此我们需要将x添加到所有left路径和right路径的前面。我们还需要将两个列表合并为一个列表。

paths (Node x left right) = map (x:) (paths left ++ paths right)

就是这样。当然,现在你可能想看看是否有一种更有效的方法来实现它,或者如果这里有一个共同的模式(即我们可以把它写成折叠吗?)。

答案 1 :(得分:0)

这里的答案非常简单,所以对于一个Tree结构,例如你提供的那个,如果我们有:

Intent intent = getIntent();
int score = intent.getIntExtra("score",0);

我们需要在函数中使用嵌套函数,基本上是一个从分支返回列表的函数,这样我们可以将树的第一个参数(树干或初始值)与任一个分支的值分开,但我确信有更高效的实现,所以这里是:

data Tree = Node Int Tree Tree | Leaf

返回

traverse :: Tree a -> [[Int]] -- Do not use "a" in the return type 
traverse Leaf = [[]]
traverse (Node value left right) = [value] ++ treeToList left : [value] ++ treeToList right : []
 where treeToList Leaf = []
       treeToList (Node a left right) = [a] ++ treeToList left ++ treeToList right

小心返回类型为树a 表示a是多态的,但构造函数 Node 仅采用 Int 类型的值,表示返回的列表只能是Int。

类型