如何为OCaml中的列表列表传递二叉树?

时间:2016-03-23 23:13:16

标签: ocaml

我需要为列表列表传递二叉树,但不知道如何继续。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

将树结构(或更一般地说是森林)视为列表列表的常用方法是其路径表示"。您可以将二叉树表示为从根到叶的所有路径的数据(因此您拥有与树中的叶子一样多的路径)。

示例:

      /\
     /  \
    /    \
   /\    /\
    /\  /\
         /\

可以表示为以下列表:

  1. 左,左
  2. 左,右,左
  3. 左,右,右
  4. 右,左,左
  5. 右,左,右,左
  6. 右,左,右,右
  7. 右,右
  8. 这种表现形式有很多种。例如,当节点携带信息时,更容易将图表表示为每个节点(而不仅仅是叶子)的路径列表。因此,您可能需要调整此答案以解决您的特定问题。

    这可以通过以深度优先的方式遍历树来构建。相反,您可以递归地从路径列表重建树。

    type binary_tree =
      | Empty
      | Node of binary_tree * binary_tree
    
    type branch =
      | Left
      | Right
    
    let rec to_paths tree =
      match tree with
      | Empty -> [[]]
      | Node (left, right) ->
          (List.map (fun l -> Left :: l) (to_paths left))
        @ (List.map (fun l -> Right :: l) (to_paths right))
    
    let rec of_paths = function
      | [[]] -> Empty
      | l ->
        let lefts, rights = List.partition (function
           | [] -> failwith "of_paths: not at binary tree"
           | Left :: _ -> true
           | Right :: _ -> false) l
        in
        Node (of_paths (List.map List.tl lefts),
              of_paths (List.map List.tl rights))
    
    (* A little test : *)    
    let tree =
      Node (Node(Empty, Node (Empty, Empty)),
            Node (Node(Empty, Node (Empty, Empty)), Empty))
    
    let () = assert (tree = of_paths (to_paths tree))