繁体   English   中英

创建所有大小为n的Bool二叉树

[英]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呢? 事实证明,如果BinTip增加大小,则不存在任何大小为2的树。 任何Bin导致1 + k + j的额外大小,其中kj必须是有效的树大小。 可以看到,这只会生成奇数大小的树。

因此,我们可以在继续之前丢弃所有无效的Int

> genTrees n | even n || n <= 0 = []
> genTrees n =

现在我们知道我们的n是奇数,至少是3。 因此,我们确实必须将Bin用作其他树的根。 其他树木? 好吧,还记得上面的公式吗? 我们需要生成两个新的树,它们的大小分别为jk ,使得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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM