我有以下代码在图中执行BFS:
open Queue
type 'a node = {id: 'a; edges: 'a list}
type 'a graph = 'a node list
let bfs g s =
let seen = Array.make (Array.length g) false
and treated = Queue.create() in
Queue.add s treated ; seen.(s) <- true ;
let rec add_neighbors = function
|[] -> ()
|t::q when seen.(t) -> add_neighbors q
|t::q -> Queue.add t treated ; seen.(t) <- true ; add_neighbors q
in
try while true do
let s = Queue.take treated in
print_int s ;
add_neighbors g.(s)
done
with Empty -> ()
问题是我不了解函数bfs
的工作方式。首先,我们给出图g
和第一个节点s
,但是函数add_neighbors
为:
let rec add_neighbors = function
这里的问题是该函数正在等待参数,但是我看不到代码在何处将此参数赋予函数add_neighbors
。
更准确地说。假设我有一个图g
,并且我想从节点s开始对该图执行BFS。
因此我调用了函数bfs g s
。所以这是函数的作用:
seen
的数组,其中所有条目都等于false
treated
的队列,在其中添加节点s
s
中节点seen
的值。因此,在数组seen
中,s
的值为true add_neighbors
的递归函数,但此函数在这里等待一个参数,但是在这里,我们给该函数提供的参数是什么?算法如何从这里继续?答案 0 :(得分:1)
该函数执行[创建]一个名为
seen
[…]的数组,[创建]一个名为treated
的队列[…],[并更新]节点s
的值在seen
数组中。
[然后]我们在这里调用名为add_neighbors
的递归函数,但是此函数在这里等待一个参数,但是我们给该函数提供的参数是什么?
否,let rec add_neighbors = function
不调用该函数。它使用函数值声明本地add_neighbors
,然后允许我们在以下代码块中使用此变量in
。
算法如何从此处继续?
算法执行的下一件事是块
try while true do
let s = Queue.take treated in
print_int s ;
add_neighbors g.(s)
done
with Empty -> ()
在无限循环中,它从treated
队列中取出第一个节点,进行打印,然后 then 调用add_neighbors
并假定该节点为邻居s
。此g.(s)
(或Array.get g s
)调用表明g
的类型不是graph
,而是列表的数组,数组索引是某些边的节点ID源,列表值是边缘指向的节点ID。
当Queue.take
操作抛出一个Empty
异常时,此无限循环结束,该异常被无所事事地捕获和处理。我想最好还是写
while not (Queue.is_empty treated) do
let s = Queue.take treated in
print_int s ;
add_neighbors g.(s)
done