这是一个家庭作业问题。
我的问题很简单:编写一个类型为'a btree ->'的函数btree_deepest,它返回树中最深元素的列表。如果树是空的,那么 deepest 应该返回 []。如果输入树的多个元素处于相同的最大深度,则 deepest 应返回包含这些最深元素的列表,并根据前序遍历进行排序。您的函数必须使用提供的 btree_reduce 函数,并且不能是递归的。
这是我的代码:
(* Binary tree datatype. *)
datatype 'a btree = Leaf | Node of 'a btree * 'a * 'a btree
(* A reduction function. *)
(* btree_reduce : ('b * 'a * 'b -> 'b) -> 'b -> 'a tree -> 'b) *)
fun btree_reduce f b bt =
case bt of
Leaf => b
| Node (l, x, r) => f (btree_reduce f b l, x, btree_reduce f b r)
(* btree_size : 'a btree -> int *)
fun btree_size bt =
btree_reduce (fn(x,a,y) => x+a+y) 1 bt
(* btree_height : 'a btree -> int *)
fun btree_height bt =
btree_reduce (fn(l,n,r) => Int.max(l, r)+1) 0 bt
我知道我必须创建一个函数来传递给 btree_reduce 以构建最深元素的列表,这就是我步履蹒跚的地方。
如果允许我使用递归,那么我将只比较左右节点的高度,然后在更高的分支上递归(或者如果它们的高度相同,则在两者上递归),然后在高度为零时返回当前元素和将这些元素放入列表中。
我想我只需要朝着正确的方向努力就可以开始了……
谢谢!
更新:
这是一个无法编译的解决方案的尝试:
fun btree_deepest bt =
let
val (returnMe, height) = btree_reduce (fn((left_ele, left_dep),n,(right_ele, right_dep)) =>
if left_dep = right_dep
then
if left_dep = 0
then ([n], 1)
else ([left_ele::right_ele], left_dep + 1)
else
if left_dep > right_dep
then (left_ele, left_dep+1)
else (right_ele, right_dep+1)
)
([], 0) bt
in
returnMe
end