練習問題 6.7

二分木の左右を反転させた木を返す関数 reflect を定義しなさい。

reflect comptree;;

: int tree =
Br(1, Br(3, Br(7, Lf, Lf), Br(6, Lf, Lf)),
Br(2, Br(5, Lf, Lf), Br(4, Lf, Lf)))

また、任意の二分木 t に対して成立する、次の方程式を完成させなさい。
preorder(reflect(t)) = ?
inorder(reflect(t)) = ?
postorder(reflect(t)) = ?

(* 二分木 *)

(* 定義 *)
type 'a tree = Lf | Br of 'a * 'a tree * 'a tree;;

(* 完全木 *)
let comptree = Br(1, Br(2, Br(4, Lf, Lf),
Br(5, Lf, Lf)), Br(3, Br(6, Lf, Lf),
Br(7, Lf, Lf)));;

let mytree = Br('a', Br('b', Lf, Lf), Br('c', Br('d', Lf, Lf), Br('e', Lf, Lf)));;

解答

let rec reflect t =
    match t with
    Lf -> Lf
    | Br (x, left, right) ->
            Br (x, (reflect right), (reflect left));;

(* 実行例 *)
# reflect comptree;;
- : int tree =
Br(1, Br(3, Br(7, Lf, Lf), Br(7, Lf, Lf)),
 Br(2, Br(5, Lf, Lf), Br(4, Lf, Lf)))

(* 行きがけ順 -- preorder *)
let rec preorder = function
    Lf -> []
    | Br (x, left, right) -> 
            x :: (preorder left) @ (preorder right);;

(* 通りがけ順 -- inorder *)
let rec inorder = function
    Lf -> []
    | Br (x, left, right) ->
            (inorder left) @ (x :: inorder right);;

(* 帰りがけ順 -- postorder *)
let rec postorder = function
    Lf -> []
    | Br (x, left, right) ->
            (postorder left) @ (postorder right) @ [x];;


(* reverse 関数 *)
let rec reverse = function
    [] -> []
  | v :: rest -> reverse rest @ [v];;

let t = comptree;;

完成させた方程式は、以下。

let test1 = preorder(reflect(t)) = reverse (postorder t);;  (* true *)
let test2 = inorder(reflect(t)) = reverse (inorder t) ;;    (* true *)
let test3 = postorder(reflect(t)) = reverse (preorder t);;  (* true *)