在递归树类型中查找'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
我尝试过使用递归和辅助功能,但最终却非常混乱而没有成功。
答案 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.choose
和List.tryFind
,我使用Seq
因此会在tryFind
提前停止。
此外,此版本在名称上具有谓词匹配。如果总是想要使用相等性,则可以将名称添加为参数,并将p
和name
交换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", []))