具有递归数据类型的二叉树的后序遍历
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有递归数据类型的二叉树的后序遍历相关的知识,希望对你有一定的参考价值。
我正在尝试为递归数据类型的后序遍历创建一个函数,该函数创建一个二叉树,其中示例可以创建尽可能多的子叶。我试图将节点设置为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]
| ^^^^
我不明白为什么离开:右:root不会绑定,为什么在列表中调用带有追加的postord将不会按原样编译右节点,左节点和root中的每个节点的列表。
答案
N
没有特定的左右儿童,它当然没有任何明显的根值;它只有一个任意的儿童名单。
你BiTree
只存储叶子中的值。与N
值唯一相关的是将postord
映射到每个子节点,并将结果连接到单个列表中。 (因此,在订单前,订单和订单后的遍历之间没有真正的区别。)
postord :: BiTree a -> [a]
postord (L x) = [x]
postord (N children) = concatMap postord children
现在,如果您有一个在内部节点中存储值的类型,那么您的类型可能是这样的
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]
将单个值附加到较长的列表并不理想,但这是另一个问题的问题。
另一答案
不知道我是否理解你的问题,但是这个怎么样:
postord :: BiTree a -> [a]
postord (L x) = [x]
postord (N cs) = concatMap postord cs
以上是关于具有递归数据类型的二叉树的后序遍历的主要内容,如果未能解决你的问题,请参考以下文章