I have a question I'm working on, where I have to traverse a tree once and count how many children each node has.
There are two parts to this, the datatype, and the function itself.
Datatype
The datatype requires that the internal nodes store a value of any type and have anywhere from 1-3 children. The leaves themselves store either a real number or a string list.
datatype leaf = Slist of string list | Real of real;
datatype tree = Empty
| Leaf of leaf
| Node of leaf * 'a tree
| Node of leaf * 'a tree * 'a tree
| Node of leaf * 'a tree * 'a tree * 'a tree
Function
Next, I have to define a function that takes a tree, and returns a tuple (n1, n2, n3), where n1 is the number of nodes having one child, n2 number of nodes with two children, n3 number of nodes with three children.
fun myChildren (t:'a tree) = childHelper (t, (0,0,0));
fun childHelper (t: 'a tree, (n1, n2, n3):int*int*int) =
case t of
Empty => 0
| Node (x) => childrenHelper(t, (n1 + 1, n2, n3))
| Node (x, y) => childrenHelper(t, (n1 + 1, n2 + 1, n3))
| Node (x, y, z) => childrenHelper(t, (n1 + 1, n2 + 1, n3 + 1));
I'm just starting to use datatypes and cases, so it's confusing for me. I was wondering, are my datatypes the best way to represent the tree? And how do I make my function recursively go through the tree? As it stands, it just counts the first node of the tree instead of all of it. I'm also leaving off the case that it's a leaf, since at that point I don't need to do anything.
I know that in a list, you can do hd::tl, is there a way I can do that on the tree so that, having gone through the node, I call the function on each node?
For example, for Node (x, y, z)
, it should call childrenHelper on each node, but at the same time, maintain the number on the tuples. Any ideas on how to go forward with this?