これは宿題の質問です。
私の質問は簡単です: ツリーの最も深い要素のリストを返す 'a btree -> 'a リスト型の関数 btree_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