我正在OCaml中实施in-place graph BFS
。
这是我的代码:
type graph = {s : int list array;num_v:int;mutable num_e : int};;
let bfs u g p =
let marker = Array.make g.num_v false
in
let q = Queue.create()
in
Queue.push u q;
let rec add_to_queue v = function
| [] -> ()
| hd::tl ->
if not marker.(hd) then begin
marker.(hd) <- true;
Queue.push hd q;
p.(hd) <- v
end;
add_to_queue v tl
in
**let rec bfs_go =**
if Queue.length q > 0 then begin
let v = Queue.pop q
in
print_int v;
add_to_queue v g.s.(v);
bfs_go
end
in
bfs_go;;
我认为代码很好,但编译器给了我这个错误:
File "", line 20, characters 4-177: Error: This kind of expression is not allowed as right-hand side of 'let rec'
我bfs_go
的实现似乎有问题(我标有** **),但为什么呢?我看不出任何错误。
修改
功能样式 DFS
let dfs_better u g p =
let marker = Array.make g.num_v false in
let rec dfs_go current next =
match current, next with
| [], _ -> ()
| parent::[], [] -> ()
| parent::next_parent::rest, [] -> dfs_go (next_parent::rest) g.s.(next_parent)
| parent::rest, node::tl ->
if not marker.(node) then begin
print_int node;
marker.(node) <- true;
p.(node) <- parent;
dfs_go next g.s.(node)
end;
dfs_go current tl in
marker.(u) <- true;
dfs_go [u] g.s.(u);;
答案 0 :(得分:6)
你可能意味着
let rec bfs_go () =
...;
bfs_go ()
而不是
let rec bfs_go =
...;
bfs_go
编辑:我无法抗拒一些改进。
用你的命令式:
let bfs start graph from =
let marker = Array.make graph.num_v false in
let q = Queue.create() in
let add_to_queue parent node =
if not marker.(node) then begin
marker.(node) <- true;
Queue.push node q;
from.(node) <- parent;
end in
Queue.push start q;
while not (Queue.is_empty q) do
let node = Queue.pop q in
print_int node;
List.iter (add_to_queue node) graph.s.(node)
done
如果你想要更实用的东西:
let bfs start graph from =
let marker = Array.make graph.num_v false in
let rec bfs current next = match current, next with
| [], [] -> ()
| [], (_::_ as next) -> bfs next []
| node::current, next ->
let add parent node next =
if marker.(node) then next
else begin
marker.(node) <- true;
from.(node) <- parent;
node :: next
end in
print_int node;
bfs current (List.fold_right (add node) graph.s.(node) next)
in bfs [start] []
编辑2:
尝试DFS问题,完全未经测试(刚编译):
使用数据结构处理要访问的节点:
let dfs u g p =
let marker = Array.make g.num_v false in
let rec dfs_go = function
| [] -> ()
| node::next ->
print_int node;
let children =
List.filter (fun child -> not marker.(child)) g.s.(node) in
List.iter (fun child -> marker.(child) <- true) children;
dfs_go (children @ next)
in
marker.(u) <- true;
dfs_go [u];;
仅使用(非尾部)递归:
let dfs u g p =
let marker = Array.make g.num_v false in
let rec dfs_go node =
print_int node;
let go_child child =
if not marker.(child) then begin
marker.(child) <- true;
dfs_go child;
end in
List.iter go_child g.s.(node)
in
marker.(u) <- true;
dfs_go u;;