I'm trying to create all binary trees of size n, But can't think of a way to do it.
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.
> 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.
I can't think about a way to generate all the Trees of size 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. So what about 2
? It turns out that there does not exist any tree of size two, if both Bin
and Tip
increase the size. Any Bin
leads to an additional size of 1 + k + j
, where k
and j
must be valid tree sizes. One can see that this yields only trees of odd size.
We can therefore discard any invalid Int
s before we continue:
> genTrees n | even n || n <= 0 = []
> genTrees n =
Now we know that our n
is odd, and at least three. Therefore, we really have to use a Bin
as a root for our other trees. 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
. Luckily, we have a function to generate those trees, called 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. What are now valid tree sizes? Tip
s contribute to the size (after all, only they have a payload). 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.