Reputation: 21
Could anyone please help me with my assignment questions? I've done most of it but I'm still stuck on these 3 questions.
Here is the question:
Consider the following types of search trees and balanced trees
data STree = Leaf | Node STree Int STree data Btree = Tip Int | Branch Btree Btree
whose constructors are subject to the following constraints:
- Values of the form
Node left n right
must have all integers in left being at mostn
and all integers in right being greater thann
.- Values of the form
Branch left right
must have a difference between the numbers of integers inleft
andright
of at most one.a) Define a recursive function
stree :: [Int] -> STree
that constructs a search tree from a list of integers.b) Define a recursive function
btree :: [Int] -> BTree
that constructs a balanced tree from a non-empty list of integers.c) Using merge, define a recursive function
collapse :: BTree -> [Int]
that collapses a balanced tree to give a sorted list of integers.
Please help me!!!
Thanks very much in advance!
Upvotes: 2
Views: 1432
Reputation: 234
These are recursive data structures. Let's start with the Search Tree:
data STree = Leaf | Node STree Int STree
and all values in the left must be less than the parent, which must be less than all values in the right. Can you write down the answers for stree [] and stree [x]? How far can you go?
I'll start:
stree [] = Leaf
stree [x] = Node Leaf x Leaf
stree ([x,y]) = if x < y then Node Leaf x (Node Leaf y Leaf) else Node (Node Leaf y Leaf) x Leaf
That sort of nested if and node construction is going to get awful pretty fast. What common sub-expressions can we factor out?
singleton x = Node Leaf x Leaf
That makes life a little easier:
stree [] = Leaf
stree [x] = singleton x
stree ([x,y]) = if x < y then Node Leaf x (singleton y) else Node (singleton y) x Leaf
But it doesn't attack the basic problem of the nested if. One common trick for lists is to take them one element at a time. Can that work for us?
addToSTree :: Int -> STree -> STree
addToStree x Leaf = singleton x
addToStree x (Node left n right) | x < n = ...
| otherwise = ...
Can you fill in the dots above? Once you have that, then it'll be time to make a loop over the contents of the list.
BTree can be solved similarly.
Upvotes: 0
Reputation: 89123
stree = foldr insert Leaf
where insert :: Int -> STree -> STree
insert i (Node l i' r) | i <= i' = Node (insert i l) i' r
| otherwise = Node l i' (insert i r)
insert i (Leaf) = Node Leaf i Leaf
This isn't a very efficient solution, nor does it produce a very balanced tree, but it's a good example of how to iteratively build a data structure in Haskell. Using foldr
to handle the iteration for us, we insert one element at a time into the tree, passing the new tree into the function that builds the next. We descend through the tree, until we find a leaf, and replace that Leaf
with a Node
to hold the given value.
Upvotes: 0
Reputation: 4253
Don't want to take all the fun, but here is my go at part a.
stree :: [Int] -> Stree
stree [] = Leaf
stree (x:xs) = let (left, right) = partition (<= x) xs
in Stree (stree left) x (stree right)
It just takes the components that should be on the left and right and recursively builds the subtrees for each.
Assuming the use of sort is legit, then I'm pretty certain this works for part b.
btree :: [Int] -> Btree
btree (x:[]) = Tip x
btree xs = let len = length xs `div` 2
ys = sort xs
in Branch (btree (take len ys)) (btree (drop len ys))
Upvotes: 2