简体   繁体   English

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

[英]Creating all Bool binary trees of size n

I'm trying to create all binary trees of size n, But can't think of a way to do it. 我正在尝试创建大小为n的所有二叉树,但是想不出办法。

The Tree is defined like this 树是这样定义的

> data Tree :: * -> * where
>     Tip :: a -> Tree a
>     Bin :: Tree a -> Tree a -> Tree a  
>     deriving (Eq,Show)

A size of a tree is the number of Tips and Bins it has. 一棵树的大小是指它具有的“技巧”和“箱”的数量。

I need to create a function that gets an Int n and returns a list of all the trees of that size. 我需要创建一个获取Int n并返回该大小的所有树的列表的函数。

> getTrees :: Int -> [Tree Bool]

For example for getTrees 1 I should Get [Tip True, Tip False] since this is all the possible trees of size 1. 例如对于getTrees 1我应该得到[Tip True, Tip False]因为这是所有可能的大小为1的树。

I can't think about a way to generate all the Trees of size n. 我想不出一种方法来生成所有大小为n的树。

Let's start with the easy ones first: the trees of size one: 让我们先从简单的树开始:一号树:

> getTrees :: Int -> [Tree Bool]
> genTrees 1 = [Tip True, Tip False]

Now, we have to think about greater Int s. 现在,我们必须考虑更大的Int So what about 2 ? 那么2呢? It turns out that there does not exist any tree of size two, if both Bin and Tip increase the size. 事实证明,如果BinTip增加大小,则不存在任何大小为2的树。 Any Bin leads to an additional size of 1 + k + j , where k and j must be valid tree sizes. 任何Bin导致1 + k + j的额外大小,其中kj必须是有效的树大小。 One can see that this yields only trees of odd size. 可以看到,这只会生成奇数大小的树。

We can therefore discard any invalid Int s before we continue: 因此,我们可以在继续之前丢弃所有无效的Int

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

Now we know that our n is odd, and at least three. 现在我们知道我们的n是奇数,至少是3。 Therefore, we really have to use a Bin as a root for our other trees. 因此,我们确实必须将Bin用作其他树的根。 Other trees? 其他树木? Well, remember the formula above? 好吧,还记得上面的公式吗? We need to generate two new trees with size j and k such that 1 + j + k = n . 我们需要生成两个新的树,它们的大小分别为jk ,使得1 + j + k = n Luckily, we have a function to generate those trees, called genTrees . 幸运的是,我们有一个生成这些树的函数,称为genTrees We can combine all in a single list comprehension: 我们可以将所有内容合并到一个列表中:

>   [Bin l r | i <- [1,3..n-1], l <- genTrees i, r <- genTrees (n - 1 - i)]

Exercises 练习题

  • Prove that all used sizes in the list comprehension are valid, including the resulting tree size as well as the intermediate tree sizes. 证明列表推导中所有使用的大小都是有效的,包括结果树的大小以及中间树的大小。
  • While the second paragraph provided some motivation, it didn't provide a complete proof that valid trees must have odd size. 尽管第二段提供了一些动机,但它没有提供完整的证据证明有效树的大小必须为奇数。 Prove that statement. 证明那句话。
  • Now count only Tip as size. 现在仅将“ Tip视为大小。 What are now valid tree sizes? 现在有效的树大小是多少?
  • Rewrite the algorithm above in order to generate trees where only Tip s contribute to the size (after all, only they have a payload). 重写上面的算法,以生成树,其中只有Tip有助于大小(毕竟,只有它们具有有效负载)。

ok I guess some dislike the way I tried to lead to the solution so without further due: here is one : 好的,我想有些不喜欢我尝试导致解决方案的方式,因此无需进一步说明:这是一个

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

note: 注意:

you can see here that you will get problems with even-sized trees because those will at some time get to getTrees 0 which will pull leftSize <- [0..(-2)] and will end right there with an empty list 您可以在此处看到偶数大小的树会遇到问题,因为这些树有时会到达getTrees 0 ,这将把leftSize <- [0..(-2)]拉到leftSize <- [0..(-2)]并以一个空列表结束

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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