0

Assume I have a binary tree:

data Bst a = Empty | Node (Bst a) a (Bst a)

I have to write a function that searches for a value and returns the number of its children. If there is no node with this value, it returns -1. I was trying to write both BFS and DFS, and I failed with both.

3
  • 2
    Please show us the code for your attempts, which will help us pinpoint where things are going wrong. Commented Jan 7, 2013 at 14:28
  • Also Haskell uses Maybe a = Nothing | Just a to express that an element wasn't found. Commented Jan 7, 2013 at 15:14
  • Look at the Tree implementation here. There are functions called treeInsert and treeElem. They can give an intuition of how to traverse the tree to implement your functions. Commented Sep 23, 2014 at 20:31

2 Answers 2

2

Pattern matching is your friend. Your Bst can either be Empty or a Node, so at the toplevel, your search function will be

search Empty = ...
search (Node left x right) = ...

Can an Empty tree possibly contain the target value? With a Node the target value, if present, will be either the node value (x above), in the left subtree, in the right subtree—or perhaps some combination of these.

By “return[ing] the number of its children,” I assume you mean the total number of descendants of the Bst rooted at a Node whose value is the target, which is an interesting combination of problems. You will want another function, say numChildren, whose definition uses pattern matching as above. Considerations:

  1. How many descendants does an Empty tree have?
  2. In the Node case, x doesn’t count because you want descendants. If only you had a function to count the number of children in the left and right subtrees …
Sign up to request clarification or add additional context in comments.

1 Comment

I'd just add that the other magic word he needs is recursion. With pattern matching and recursion the assignment it is very easy.
1

Here is a way to do this. Breath-first search can actually be a bit tricky to implement and this solution (findBFS) has aweful complexity (appending to the list is O(n)) but you'll get the gist.

First I have decided to split out the finding functions to return the tree where the node element matches. That simplifies splitting out the counting function. Also, it is easier to return the number of elements than the number of descendants and return -1 in case not found, so the numDesc functions rely on the numElements function.

data Tree a = Empty
            | Node a (Tree a) (Tree a)

numElements :: Tree a -> Int
numElements Empty        = 0
numElements (Node _ l r) = 1 + numElements l + numElements r

findDFS :: Eq a => a -> Tree a -> Tree a
findDFS _ Empty                         = Empty
findDFS x node@(Node y l r) | x == y    = node
                            | otherwise = case findDFS x l of 
                                            node'@(Node _ _ _) -> node'
                                            Empty              -> findDFS x r

findBFS :: Eq a => a -> [Tree a] -> Tree a                                                                
findBFS x []                              = Empty
findBFS x ((Empty):ts)                    = findBFS x ts
findBFS x (node@(Node y _ _):ts) | x == y = node
findBFS x ((Node _ l r):ts)               = findBFS x (ts ++ [l,r])

numDescDFS :: Eq a => a -> Tree a -> Int
numDescDFS x t = numElements (findDFS x t) - 1

numDescBFS :: Eq a => a -> Tree a -> Int
numDescBFS x t = numElements (findBFS x [t]) - 1

1 Comment

I can't understand what's going on after otherwise... could you explain it more?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.