我正在使用OCaml。我有类型:
type 'a bt = Empty | Node of 'a * 'a bt * 'a bt;;
我也有BST示例:
let tree = Node(1,Node(2,Node(4,Empty,Empty),Empty),Node(3,Node(5,Empty,Node(6,Empty,Empty)),Empty));
我需要编写函数:breadthBT : 'a bt -> 'a list
,这将是广度优先搜索遍历。对于上面的示例树,它应该返回[1; 2; 3; 4; 5; 6]
如何编写该功能?我只能编写以下使用 DST :
的功能let rec breadthBT tree =
if tree=Empty then []
else let Node(w,l,r)=tree in (w::breadthBT l)@breadthBT r;;
上面的函数返回(例如树)[1; 2; 4; 3; 5; 6]。但我不能写使用 BFS 的功能。你能帮帮我吗?
答案 0 :(得分:5)
这不是可编译的解决方案。只是一个提示。
您应该从顶级根节点迭代到深层节点。让我们的函数接收答案的累加器和节点列表(你的'a bt值)作为第二个参数。您可以通过获取三元组的第一个元素来映射此列表,而不是接收下一部分答案。您还需要评估下一级树。对于每个节点,最多有两个后代。您可以映射列表并应用_a_function_
来接收后代列表。它将是你树的下一级。而不是---递归。
A不会指定此_a_function_
。尝试研究google中的concatMap是什么。
快乐的黑客攻击!
答案 1 :(得分:1)
想象一下,你把鼻子贴在树上。是否可以以广度优先的方式遍历树,而无需在记事本中添加书签位置?不,因为订单可以让您从一个分支跳转到另一个不相关的分支。所以你需要一个带有“剩余位置”的记事本。你从记事本中选择下一个剩下的位置然后盲目地跳到它。由于您从记事本中删除了访问位置,因此您处于尚未访问过的节点。由于您无法访问中间节点而无法启动树,因此您尚未访问现在位于您上方的两个节点。但你抵制直接攀爬树枝的本能 - 哎呀,这是广度的第一顺序。您不想忘记这两个未访问的节点,因此您希望将它们放入笔记本中。你把它们放在笔记本电脑前面还是背面?当然,在后面,否则你会立即选择其中一个,这就是我们想要避免的。 Et voila:你的记事本是节点的FIFO队列,你作为累加器保存(即传递),但也消耗选择要访问的子树。