我正在尝试为递归数据类型的后遍历创建一个函数,该函数创建一个二叉树,其中示例可以创建尽可能多的子叶子。我试图将节点设置为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不绑定,为什么用追加调用列表中的postord不会按原样编译右节点,左节点和root中每个节点的列表
答案 0 :(得分:1)
N
没有特定的左,右子级,并且肯定没有任何可区分的根值; just 有一个任意的孩子列表。
您BiTree
仅将值存储在叶子中。与N
值唯一相关的是将postord
映射到每个孩子,并将结果串联到一个列表中。 (因此,预订前,订单中和订单后遍历之间没有真正的区别。)
postord :: BiTree a -> [a]
postord (L x) = [x]
postord (N children) = concatMap postord children
现在,如果您有一个 did 在内部节点中存储值的类型,则您的类型可能看起来像
data BiTree a = L a | N a [BiTree a]
然后,您的后订单遍历必须考虑存储在内部节点中的值,类似于您先前的尝试。
postord :: BiTree a -> [a]
postord (L x) = [x]
postord (N v children) = concatMap postord children ++ [v]
将单个值添加到较长的列表并不理想,但这是另一个问题的问题。
答案 1 :(得分:0)
不知道我是否理解您的问题,但是呢:
postord :: BiTree a -> [a]
postord (L x) = [x]
postord (N cs) = concatMap postord cs