【发布时间】:2019-04-11 15:17:00
【问题描述】:
我正在尝试为递归数据类型的后序遍历创建一个函数,该函数创建一个二叉树,其中示例可以创建尽可能多的子叶。我尝试将节点设置为 left:root:right 但错误无法识别它们 - 但是,它会识别 (y:ys)。无论我使用 () 或 [] 还是周围什么都没有,它也将 root 识别为 Int。我错过了什么?
这是数据类型和一些简单的测试示例:
data BiTree a = L a
| N [BiTree a]
ex1 :: BiTree Int
ex1 = N [(L 1),(L 1),(L 3)]
ex2 :: BiTree Int
ex2 = N [(L 1),(N[(L 2),(L 3)]),(L 4)]
这是我写的代码:
postord :: BiTree a -> [Int]
postord (L x) = [x]
postord (N (left:root:right)) = postord (N right) ++ postord (N left) ++ [root]
这是错误:
* Couldn't match expected type `Int' with actual type `BiTree a'
* In the expression: root
In the second argument of `(++)', namely `[root]'
In the second argument of `(++)', namely
`postord (N left) ++ [root]'
* Relevant bindings include
right :: [BiTree a] (bound at try.hs:21:23)
root :: BiTree a (bound at try.hs:21:18)
left :: BiTree a (bound at try.hs:21:13)
postord :: BiTree a -> [Int] (bound at try.hs:20:1)
|
21 | postord (N (left:root:right)) = postord (N right) ++ postord (N left) ++ [root]
| ^^^^
我不明白为什么 left:right:root 不会绑定,为什么用 appends 调用列表中的 postord 不会编译右节点、左节点和 root 中每个节点的列表.
【问题讨论】:
-
在我看来,您在传递子树列表的版本中混合了一个真正的二叉树(它会有一个看起来完全不同的
data声明)。 (要成为真正的二叉树,该列表只会有 2 个元素,但这种类型不会强制执行此操作,您已经给出了 3 个的示例。) -
后序遍历是处理分支的所有子项,然后处理分支中的值。但是,您不会将值存储在分支中,而只是存储在叶子中,因此后序或前序遍历的想法对于这种结构毫无意义。您编写的代码实际上会做的(如果编写正确的话)是将第三个孩子,第四个孩子等按顺序处理到最后一个孩子,然后是第一个孩子,然后是第二个孩子。我怀疑这就是你想要的。
标签: haskell