[英]Creating all Bool binary trees of size n
我正在尝试创建大小为n的所有二叉树,但是想不出办法。
树是这样定义的
> data Tree :: * -> * where
> Tip :: a -> Tree a
> Bin :: Tree a -> Tree a -> Tree a
> deriving (Eq,Show)
一棵树的大小是指它具有的“技巧”和“箱”的数量。
我需要创建一个获取Int n
并返回该大小的所有树的列表的函数。
> getTrees :: Int -> [Tree Bool]
例如对于getTrees 1
我应该得到[Tip True, Tip False]
因为这是所有可能的大小为1的树。
我想不出一种方法来生成所有大小为n的树。
让我们先从简单的树开始:一号树:
> getTrees :: Int -> [Tree Bool]
> genTrees 1 = [Tip True, Tip False]
现在,我们必须考虑更大的Int
。 那么2
呢? 事实证明,如果Bin
和Tip
增加大小,则不存在任何大小为2的树。 任何Bin
导致1 + k + j
的额外大小,其中k
和j
必须是有效的树大小。 可以看到,这只会生成奇数大小的树。
因此,我们可以在继续之前丢弃所有无效的Int
:
> genTrees n | even n || n <= 0 = []
> genTrees n =
现在我们知道我们的n
是奇数,至少是3。 因此,我们确实必须将Bin
用作其他树的根。 其他树木? 好吧,还记得上面的公式吗? 我们需要生成两个新的树,它们的大小分别为j
和k
,使得1 + j + k = n
。 幸运的是,我们有一个生成这些树的函数,称为genTrees
。 我们可以将所有内容合并到一个列表中:
> [Bin l r | i <- [1,3..n-1], l <- genTrees i, r <- genTrees (n - 1 - i)]
Tip
视为大小。 现在有效的树大小是多少? Tip
有助于大小(毕竟,只有它们具有有效负载)。 好的,我想有些不喜欢我尝试导致解决方案的方式,因此无需进一步说明:这是一个 :
getTrees :: Int -> [Tree Bool]
getTrees 1 = [Tip True, Tip False]
getTrees n = do
leftSize <- [0..n-2]
let rightSize = (n-1) - leftSize
left <- getTrees leftSize
right <- getTrees rightSize
return $ Bin left right
您可以在此处看到偶数大小的树会遇到问题,因为这些树有时会到达getTrees 0
,这将把leftSize <- [0..(-2)]
拉到leftSize <- [0..(-2)]
并以一个空列表结束
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.