練習問題 6.12

格納された要素が 1, 2, 3, 4 になるよう二分木探索木の形をすべて列挙し、それぞれの形を作るためには空の木から初めて、どの順番で要素を add していけばよいか示しなさい。

解答

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


(* 要素を木に追加する *)
let rec add t x =
    match t with
    Lf -> Br (x, Lf, Lf)
    | (Br (y, left, right) as whole) when x = y -> whole
    | Br (y, left, right) when x < y -> Br (y, add left x, right)
    | Br (y, left, right) -> Br (y, left, add right x);;

(* 空の木 *)
let mytree = Lf;;

(* 要素をリストにして、それを順に木に追加する。
    t -- tree, l -- list   *)
let rec addx t l =
    match l with
      [] -> t
    | v :: rest ->
       addx (add t v) rest;;

(* リストの中の順番を変えて、木に追加する *)
let test1 = addx mytree [3; 1; 2; 4] = Br (3, Br (1, Lf, Br (2, Lf, Lf)), Br (4, Lf, Lf));;
let test2 = addx mytree [3; 2; 1; 4] = Br (3, Br (2, Br (1, Lf, Lf), Lf), Br (4, Lf, Lf));;
let test3 = addx mytree [2; 1; 3; 4] = Br (2, Br (1, Lf, Lf), Br (3, Lf, Br (4, Lf, Lf)));;
let test4 = addx mytree [2; 4; 3; 1] = Br (2, Br (1, Lf, Lf), Br (4, Br (3, Lf, Lf), Lf));;
図にあらわすと、以下のようになる
test1           test2
      3            3
   +--+--+      +--+--+
   1     4      2     4
   +-+        +-+
     2        1
     
test3            test4
      2            2
   +--+--+      +--+--+
   1     3      1     4
         +-+        +-+
           4        3