OCaml中的二叉搜索树预编码算法

时间:2017-09-18 10:17:04

标签: algorithm ocaml binary-search-tree

我在OCaml中实现此算法时遇到问题,因为我必须在函数之间打印括号。

算法如下:

BEGIN
   WRITE ( "(" )
   IF (NOT EMPTY tree) THEN 
      IF (NOT EMPTY (left_leaf tree)) OR (NOT EMPTY (right_leaf tree)) THEN BEGIN
        WRITE (" ", root tree, " ")
        preorder (left_leaf tree)
        WRITE (" ")
        preorder (right_leaf tree)
      END ELSE
        WRITE (" ", root tree, " ")
   WRITE ( ")" ); {this has to be always executed}
END

这是我在OCaml的不良尝试:

let rec preorderParenthesed tree = 

   print_string "(" in
   if not (isEmptyTree tree) then (
      if not (isEmptyTree(leftLeaf tree)) || not (isEmptyTree(rightLeaf tree)) then begin
        print_string " ";
        print_string (string_of_root (root tree));
        print_string " ";
        preorderParenthesed (leftLeaf tree);
        print_string " ";
        preorderParenthesed (rightLeaf tree);
      end else
        print_string " ";
        print_string (string_of_root (root tree));
        print_string " "; 
    ) 
    else if true then print_string ")\n";;

任何帮助将不胜感激

type bst = 
Empty   
| Node of (key * bst * bst);;

3 个答案:

答案 0 :(得分:2)

我怀疑你在else分支中省略了开头/结尾:

  end else
    print_string " ";
    print_string (string_of_root (root tree));
    print_string " "; 

答案 1 :(得分:2)

使用模式匹配可以简化您的功能:

type 'a bst = Empty | Node of ('a * 'a bst * 'a bst)

let rec string_of_tree ~f = function
| Empty ->
  "()"
| Node (value, Empty, Empty) ->
  Printf.sprintf "(%s)" (f value)
| Node (value, left, right) ->
  Printf.sprintf "(%s %s %s)"
    (f value)
    (string_of_tree ~f left)
    (string_of_tree ~f right)

val string_of_tree : f:('a -> string) -> 'a bst -> string = <fun>
  

f只是一个string_of_*函数。

模式描述了以下情况:

  1. 树是空的
    • ()
  2. 树不是空的,但是两个子树都是
    • (value)
  3. 树不是空的,案例2.没有检查
    • (value left_subtree right_subtree)

答案 2 :(得分:2)

Preorder Traversal可能有点令人困惑,但这里有一点概述它是如何工作的:

  1. 访问当前节点
  2. 遍历左子树
  3. 遍历正确的子树
  4. 在您的代码中,我认为您正在实施遍历并同时完成工作,将两者分开可能更简单:

    let rec traversePreOrder node cb =
      match node with
      | Empty  -> "()"
      | Node (value, left, right) ->
          cb value; 
          traversePreOrder left cb; 
          traversePreOrder right cb;
    

    您可以使用上述步骤遍历节点,并在访问节点时调用回调(可以打印节点值的函数)。