我想编写一个函数,该函数返回任何给定大小的所有可能的二叉树。
不幸的是,我不知道为什么我的解决方案总是返回一个空列表(大小1除外)。
allTreesN :: Int -> t -> [Tree t]
allTreesN n t
| n == 0 = [ Leaf ]
| otherwise = [(Node x t y) | i <- [0..n-1], x <- (allTreesN i t),y <- (allTreesN i t), size (Node x t y) == n]
答案 0 :(得分:4)
您基本上为i
和x
生成了大小为y
的所有树,然后旨在构造大小为n
的树。仅在i = 2 *n
下有效。但是现在出现了第二个问题:由于1
不能被二除,因此我们在这里永远无法生成大小为1
的树。由于我们无法生成大小为1
的树,因此无法生成大小为2
的树,依此类推。
因此,我们需要确保生成的树大小正确。我们可以通过生成大小为i
的树和另一棵大小为n-i-1
的树来做到这一点。如果我们构造了一个这样大小的节点,则可以肯定地知道承载这些子树的节点的大小为n
,因此我们甚至可以省略检查。
所以正确的实现是:
allTreesN :: Int -> a -> [Tree a]
allTreesN 0 _ = [Leaf]
allTreesN n v = [Node l v r | i <- [0..n-1],
l <- allTreesN i v,
r <- allTreesN (n-1-i) v]
例如:
Prelude> allTreesN 0 'a'
[Leaf]
Prelude> allTreesN 1 'a'
[Node Leaf 'a' Leaf]
Prelude> allTreesN 2 'a'
[Node Leaf 'a' (Node Leaf 'a' Leaf),Node (Node Leaf 'a' Leaf) 'a' Leaf]
Prelude> allTreesN 3 'a'
[Node Leaf 'a' (Node Leaf 'a' (Node Leaf 'a' Leaf)),Node Leaf 'a' (Node (Node Leaf 'a' Leaf) 'a' Leaf),Node (Node Leaf 'a' Leaf) 'a' (Node Leaf 'a' Leaf),Node (Node Leaf 'a' (Node Leaf 'a' Leaf)) 'a' Leaf,Node (Node (Node Leaf 'a' Leaf) 'a' Leaf) 'a' Leaf]