Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Max Value of a Multiway Tree in OCaml

I'm an IT Student and kind of a newbie to OCaml

Recently, studying for an exam I found this exercise.

Given: type 'a tree = Tree of 'a * 'a tree list

Define a function mtree : 'a tree ->'a, that returns the greatest value of all the nodes in a multiway tree, following the usual order relation in OCaml (<=)

I've come to do something like this below, which, of course, is not working.

let rec mtree (Tree (r, sub)) =
        let max_node (Tree(a, l1)) (Tree(b, l2)) =
            if a >= b then (Tree(a, l1)) else (Tree(b, l2)) in
        List.fold_left max_node r sub;;

After reading an answer to this I'm posting the fixed code.

let rec mtree (Tree(r,sub)) =
    let max_node (Tree(a, l1)) (Tree(b, l2)) =
        if a >= b then a else b in
    List.fold_left (max_node) r (List.map mtree sub);;

The idea is the same, fold the list comparing the nodes making use of my local function to do so and travel through the tree by calling the function itself over the nodes lists of the consecutive levels.

Is still not working, though. Now complains about max_node in the fold_left part.

Error: This expression has type 'a tree -> 'a tree -> 'a
       but an expression was expected of type 'a tree -> 'a tree -> 'a tree

And here I'm definitely lost because I can't see why does it expects to return an 'a tree

like image 778
Trigork Avatar asked Jun 28 '13 17:06

Trigork


2 Answers

This code is pretty credible (IMHO). The key thing missing is that it doesn't traverse subtrees of the subtrees. Note that you define your function as recursive (which is very reasonable), but it never calls itself.

Another issue to point out is that the problem statement calls for a "value" from the tree, but your code is returning a whole tree node.

like image 198
Jeffrey Scofield Avatar answered Nov 15 '22 20:11

Jeffrey Scofield


Answering my own question is kind of lame but with the hints received here I could finish it I'm leaving my code here for anyone facing similar problems.

let maxt (Tree(r,b)) =
    let rec aux (Tree(r,b)) =
        match b with
        [] -> [r]
        |l -> [r]@( List.fold_right (@) (List.map aux b) [])
    in List.fold_left max r (aux (Tree(r,b)));;
like image 44
Trigork Avatar answered Nov 15 '22 19:11

Trigork