简体   繁体   中英

OCaml option type in binary tree

I have a few problems creating a tree size function with type 'a option tree -> int

type 'a tree = Leaf of 'a
         | Fork of 'a * 'a tree * 'a tree

How would I create a t_opt_size function with type 'a option tree -> int?

I know I would have to use Some and the None operate.

I have this so far, but it's complicated to match with the option type.

let rec t_size (tr: 'a tree): int = 
    match tr with
    | Leaf _ -> 1
    | Fork (_, t1, t2) -> t_size t1 + t_size t2 + 1

I assume from your comments that you want a leaf that looks like (Leaf None) not to be counted in your tree size calculation.

Seems like the key is to split this:

| Leaf _ -> 1

Into two cases:

| Leaf None -> (* Left as exercise *)
| Leaf (Some _) -> (* Left as exercise *)

Since OCaml will take the first match, you can abbreviate this as follows if you like:

| Leaf None -> (* Left as exercise *)
| Leaf _ -> (* Left as exercise *)

You should make a similar change to the Fork case, though I have to say that Fork (None, l, r) doesn't really work for constructing a search tree.

If you want to generalize, you might need to write a generic tree walker which accepts a visitor function. I recommend you try to implement fold_tree , which accepts: (1) a fold function, taking some value, a tree and producing a new result ( 'a -> 'bt -> 'c ), (2) an initial element of type 'a as well as (3) a tree. Then, fold_tree returns a value of type 'c . Then, you should be able to call fold_tree with a function that skips over None leaves but otherwise increment the count like you did.

If you don't want to count all values in the tree as 1, but each depending on its contents, write a function that determines the count per value and use that:

let weight = function
    | _ -> 1 (* or anything else *)

let rec t_opt_size (tr: 'a tree): int = match tr with
    | Leaf v -> weight v
    | Fork (v, t1, t2) -> t_size t1 + t_size t2 + weight v

You even might want to generalise and pass the weight function as a parameter to t_size instead of writing different size functions that all use their own weighting.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM