按顺序遍历树并将给定功能应用于所有节点

时间:2019-03-05 10:29:49

标签: .net functional-programming f#

我编写了一个有序的树遍历函数:

let rec inOrder (tree: BinTree<'a>) : 'a list =
    match tree with
    | Leaf -> []
    | Node(x,l,r) -> (inOrder l) @ [x] @ (inOrder r)

现在,我想使用此功能来“映射”所有音符并应用作为参数给出的功能。它应该带有一个函数和一棵树,然后返回一棵树。这是我到目前为止的内容:

let mapInOrder f t = 
    inOrder t
    |> Map.ofList

例如,如果我为函数提供以下输入:

mapInOrder float (Node(1,Node(2,Leaf,Leaf),Node(3,Leaf,Leaf)));;

我想要输出:

(Node(1.0,Node(2.0,Leaf,Leaf),Node(3.0,Leaf,Leaf)))

3 个答案:

答案 0 :(得分:4)

要在List上映射函数,请使用函数List.map

let mapInOrder f t = 
    inOrder t
    |> List.map f

但是此函数将产生一个List作为输出。您的示例将产生:

[ 1.0 ; 2.0 ; 3.0 ]

要产生输出,您希望mapInOrder应该遍历该树,然后将该函数应用于每个元素。

答案 1 :(得分:1)

这是我随附的:

type BinTree<'a> =
    | Leaf 
    | Node of x :'a  * l:BinTree<'a> * r:BinTree<'a>

let rec inOrder (tree: BinTree<'a>) : 'a list =
    match tree with
    | Leaf -> []
    | Node(x,l,r) -> (inOrder l) @ [x] @ (inOrder r)

let exampleTree = (Node(1,Node(2,Leaf,Leaf),Node(3,Leaf,Leaf)));;

let mapInOrder tree mapFunc = 
    tree
        |> inOrder 
        |> List.map mapFunc

let res = mapInOrder exampleTree double
//val res : double list = [2.0; 1.0; 3.0] <-------------- result of your current try

let rec copyAndMapInOrder<'b> (tree: BinTree<'a>) mapFunc : BinTree<'b> =
    match tree with
    | Leaf -> Leaf
    | Node(x,l,r) -> Node((mapFunc x), (copyAndMapInOrder l mapFunc), (copyAndMapInOrder r mapFunc))

let res2 = copyAndMapInOrder exampleTree double
//val res2 : BinTree<double> = Node (1.0,Node (2.0,Leaf,Leaf),Node (3.0,Leaf,Leaf)) <-- expected result

这段代码只是我对@AMieres上面建议的实现。

答案 2 :(得分:0)

添加到其他答案中的一件简单的事情。您可以定义折叠函数并从中导出其他函数。

let rec fold  (e: 'b) (f : 'a -> 'b -> 'b -> 'b) (tree: BinTree<'a>) : 'b =
    match tree with
    | Leaf -> e
    | Node(x,l,r) -> f x (fold e f l) (fold e f r)

let inorderTree  f t = fold Leaf (fun x l r -> Node (f x, l, r)) t
let inorderList  f t  = fold [] (fun x l r -> l @ [f x] @ r) t
let inorderList' t  = inorderList id t
let inorderTree' t  = inorderTree id t