我的书有以下函数来计算二叉树中非叶子节点的数量:
fun size Empty = 0
| size(Node(t_1, _, t_2)) = size t_1 + size t_2 + 1;
假设我想计算二叉树中的所有节点。如何修改此功能?
这就是我的想法:
fun size Empty = 0
| size(Node(Empty, _, Empty)) = 1
| size(Node(t_1, _, t_2)) = size t_1 + size t_2 + 1;
这看起来不错吗?
谢谢,
bclayman
答案 0 :(得分:1)
Matt是正确的,你的两个函数在功能上是相同的 - 两者都返回树中所有节点的计数。起初我没有注意到这一点,因为我以第一个函数计算 nonleaf 节点的面值,然后注意到你的Node(Empty,_,Empty)
模式是叶子的正确模式(如果叶子被定义为没有非空子节点的节点)。但是 - 这意味着书中的功能并不仅仅计算非叶(父)节点。如果你确实需要一个只计算父节点的函数,那么毕竟你的模式有用:
fun parents Empty = 0
| parents(Node(Empty, _, Empty)) = 0
| parents(Node(t_1, _, t_2)) = parents t_1 + parents t_2 + 1;
如果你的树的应用是一个大量使用父节点与叶节点区别的应用,你可以(以牺牲一些函数定义为代价)抛弃Node
构造函数支持单独的Parent
和Leaf
构造函数。类似的东西:
datatype 'a tree = Empty | Leaf of 'a | Parent of 'a tree * 'a * 'a tree;
然后你可以编写像
这样的函数fun countLeaves Empty = 0
| countLeaves (Leaf _) = 1
| countLeaves (Parent(t1,_,t2)) = countLeaves t1 + countLeaves t2;
所以,例如。
- val t = Parent(Parent(Leaf "2", "*", Leaf "3"), "+", Leaf "4");
- countLeaves t;
val it = 3 : int
答案 1 :(得分:1)
您提供的两个实现实际上都是相同的。第二个实现的第二种情况是你的第三种模式的特殊情况。对于你的第一个实现,size(Node(Empty,1,Empty))
将递归一个左子树,返回0,递归到右子树,返回0,然后加1,产生结果1.事实上,如果你切换顺序第二种和第三种情况,编译器会告诉你它是多余的:
test.sml:3.5-5.38 Error: match redundant
Empty => ...
Node (t_1,_,t_2) => ...
--> Node (Empty,_,Empty) => ...