给定定义为
的树数据结构data Tree = Node Int Tree Tree | Leaf
如何将其转换为沿所有路径的值列表?
例如,Node 1 (Node 2 Leaf Leaf) (Node 3 Leaf Leaf)
应转换为[[1,2], [1,3]]
。
答案 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 left
和paths 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。
类型