open Assert open Trees (* trees.ml defines the tree type below and a function 'string_of_tree' for printing trees. type tree = | Empty | Node of tree * int * tree *) ;; stop_on_failure() (* Some example trees *) (* Tree on slide "Binary Trees" *) let t1 = Node( Node( leaf 0, 2, leaf 1), 3, Node( leaf 3, 2, leaf 1)) ;; print_endline "--- t1 ---" ;; print_endline (string_of_tree t1) (* Tree on slide "Representing trees" *) let t2 = Node( Node(leaf 0, 1, leaf 3), 5, Node (Empty, 7, (Node (leaf 8, 9, Empty)))) ;; print_endline "--- t2 ---" ;; print_endline (string_of_tree t2) let t3 = Node( Empty, 7, Node( Node( Node( Node( Empty, 3, Empty), 4, Empty), 5, Empty), 6, Empty)) ;; print_endline "--- t3 ---" ;; print_endline (string_of_tree t3) (* add together all of the integers appearing in a tree *) let rec sum (t:tree) : int = begin match t with | Empty -> 0 | Node (left, x, right) -> x + sum left + sum right end let test () : bool = sum t2 = 33 ;; run_test "sum t2" test let test () : bool = sum Empty = 0 ;; run_test "sum Empty" test let test () : bool = sum (leaf 2) = 2 ;; run_test "sum (leaf 2)" test (* counts the number of nodes on the longest path from the *) (* root to a leaf node *) let rec height (t:tree) : int = begin match t with | Empty -> 0 | Node (left, _, right) -> 1 + max (height left) (height right) end let test () : bool = height t2 = 4 ;; run_test "height t2" test let test () : bool = height Empty = 0 ;; run_test "height Empty" test let test () : bool = height (leaf 2) = 1 ;; run_test "height leaf" test (* -------- Tree traversals ------------- *) (* Tree on post-order traversal quiz slide *) let t5 = Node(Node(leaf 2, 1, Empty), 0, Node(leaf 7, 6, leaf 8)) ;; print_endline "--- t5 ---" ;; print_endline (string_of_tree t5) (* returns the in-order traversal of the tree *) let rec inorder (t:tree) : int list = failwith "inorder: unimplemented" let test () : bool = inorder t5 = [2;1;0;7;6;8] ;; run_test "inorder t5" test let test () : bool = inorder Empty = [] ;; run_test "inorder Empty" test let test () : bool = inorder (leaf 2) = [2] ;; run_test "inorder leaf" test (* returns the preorder traversal of the tree *) let rec preorder (t:tree) : int list = failwith "preorder: unimplemented" let test () : bool = preorder t5 = [0;1;2;6;7;8] ;; run_test "preorder t5" test let test () : bool = preorder Empty = [] ;; run_test "preorder Empty" test let test () : bool = preorder (leaf 2) = [2] ;; run_test "preorder leaf" test (* returns the post-order traversal of the tree *) let rec postorder (t:tree) : int list = failwith "postorder: unimplemented" let test () : bool = postorder t5 = [2;1;7;8;6;0] ;; run_test "postorder t5" test let test () : bool = postorder Empty = [] ;; run_test "postorder Empty" test let test () : bool = postorder (leaf 2) = [2] ;; run_test "postorder leaf" test (* ----- Challenge Problem: level-order traversal ----- *) (* Helper function for computing the level-order traversal *) (* Note that level-order traversal doesn't follow the naturally recursive structure of the tree, instead we have to use a list to keep track of all the sub trees that have yet to be visited as we traverse from one level to another. *) let rec level_helper (l:tree list) : int list = failwith "helper unimplemented" (* returns the level order traversal of the tree *) let levelorder (t:tree) : int list = level_helper [t] (* ----- Trees as containers ------ *) (* A pre-order search through an arbitrary tree. returns true if the tree contains n *) let rec contains (t:tree) (n:int) : bool = failwith "contains: unimplemented" let test () : bool = contains Empty 3 = false ;; run_test "contains Empty" test let test () : bool = contains (leaf 2) 2 = true ;; run_test "contains leaf 2" test let test () : bool = contains (leaf 2) 3 = false ;; run_test "contains leaf 2" test let test () : bool = contains t1 1 = true ;; run_test "contains t1 1" test