F#在树中搜索F#

时间:2014-11-27 16:20:55

标签: recursion tree f# functional-programming

在递归树类型中查找'item / object / type',树类型为UNSORTED,因此二进制搜索操作不会成功。

Type Tree = T of (Name*Children)
And Children = Tree list
//findTree :Tree*Name -> Tree

我的代码(不起作用)

let rec findTree t n = List.find(fun (T(nameTree,childTree)) -> n=nameTree ) t

我尝试过使用递归和辅助功能,但最终却非常混乱而没有成功。

1 个答案:

答案 0 :(得分:2)

您的基本类型基本上是这样的(清理缺失的类型):

type Tree = 
    | Tree of (string * Tree list)

现在树是未排序的,因此您可以做的最好的是线性搜索,以递归方式向下移动子节点,直到找到匹配项。在下面的例子中,搜索深度优先:

[<CompilationRepresentationAttribute(CompilationRepresentationFlags.ModuleSuffix)>]
module Tree = 
    let find p tree = 
        let rec findInner t =
            match t with
            | Tree(n, _) when p(n) -> Some(t)
            | Tree(_, children) -> children |> Seq.choose (findInner) 
                                            |> Seq.tryFind (fun _ -> true)
            | Tree(_, []) -> None
        findInner tree

如果您愿意,可以使用List.chooseList.tryFind,我使用Seq因此会在tryFind提前停止。 此外,此版本在名称上具有谓词匹配。如果总是想要使用相等性,则可以将名称添加为参数,并将pname交换when p(n)when n = name

现在,进行一点测试:

let tree = Tree("A", 
                [Tree("B", 
                    [Tree("C",[]); 
                     Tree("D", 
                        [Tree("E",[])])
                    ]); 
                Tree("F",[])
                ])

tree |> Tree.find (fun n -> n = "B") |> printfn "%A"
tree |> Tree.find (fun n -> n = "D") |> printfn "%A"
tree |> Tree.find (fun n -> n = "E") |> printfn "%A"
tree |> Tree.find (fun n -> n = "TEST") |> printfn "%A"
tree |> Tree.find (fun n -> n = "F") |> printfn "%A"

分别打印:

Some (Tree ("B", [Tree ("C", []); Tree ("D", [Tree ("E", [])])]))
Some (Tree ("D", [Tree ("E", [])]))
Some (Tree ("E", []))
<null>
Some (Tree ("F", []))