[英]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. 事实证明,如果
Bin
和Tip
增加大小,则不存在任何大小为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
的额外大小,其中k
和j
必须是有效的树大小。 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
. 我们需要生成两个新的树,它们的大小分别为
j
和k
,使得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)]
Tip
as size. Tip
视为大小。 What are now valid tree sizes? 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
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.