生成大小为n的所有二叉树

时间:2019-01-27 10:11:42

标签: haskell binary-tree list-comprehension

我想编写一个函数,该函数返回任何给定大小的所有可能的二叉树。

不幸的是,我不知道为什么我的解决方案总是返回一个空列表(大小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]

1 个答案:

答案 0 :(得分:4)

您基本上为ix生成了大小为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]