这是一个功课问题,我正在尝试在Scheme中执行深度优先搜索功能,这是我到目前为止编写的代码:
(define explore
(λ(node visited)
(let* ([neighbors (force (cdr node))]
[next (nextNode visited neighbors)]
[is-visited (member? node visited)])
(cond
;if I have no unvisited neighbours print current node and go up one level
[(equal? next #f)
(begin
(display (car node))
(display " "))]
;if current node is not visited and I have unvisited neighbors
;print current node,mark as visited and visit it's neighbors
[(and (equal? is-visited #f) (not (equal? next #f)))
(begin
(display (car node))
(display " ")
(explore next (cons node visited)))])
;go and visit the next neighbor
(if (not (equal? (nextNode (cons next visited) neighbors) #f ))
(explore (nextNode (cons next visited) neighbors) (cons node visited))))))
'node'是当前节点
'visited'是一个巫婆列表,我跟踪我访问过的节点
'nextNode'是一个函数,返回第一个未访问的邻居(如果有的话)或#f,否则为
'会员?'测试节点是否在访问列表中
Graph表示使用相邻的使用letrec对节点的引用,这就是我在'neighbors'中使用force的原因:
例如:
(letrec([node1(list“NY”(delay(list node2 node3)))],其中node2和node3被定义为node1
我正在处理的问题是,当我退出递归时,我访问过的列表无法跟踪我访问过的某些节点,我该如何解决这个问题?
答案 0 :(得分:1)
您必须将新访问列表作为递归调用的返回值。您要么必须修改探索,以便它返回其访问列表,或者定义一个辅助函数,而不是探索。然后在你递归之后,你将不得不使用函数返回的新访问列表。
编辑: 也许更好的方法是重新调整你的功能。我认为它比它需要的更复杂。你只是在进行深度优先遍历,对吗?不是真的搜索?你可以尝试更像这样的东西,使用显式堆栈来跟踪要访问的节点,以及访问的节点列表:
(define dft
(lambda (graph)
(helper graph '(1) '())))
(define helper
(lambda (graph stack visited)
(if (empty? stack)
'() ;we're done. you've got a nice list of visited nodes now, what will you do with it? Return it?
(let ([currentNode (car stack)])
(if (member? currentNode visited)
(helper graph
;what do you think the next two parameters are?
)
(begin
(display currentNode)
(helper graph
;what do you think the next two parameters are?
))))))
由于这是一个家庭作业问题,我已经为辅助函数留下了两个参数供你填写。这种方法最好的方法是将它更改为广度优先遍历非常简单。
这是一个提示:两种不同情况的参数会略有不同。
答案 1 :(得分:0)
我也回答了here。
执行此操作的一种方法是返回列表,以便在更高级别的递归时访问它。
另一种方法是将列表存储在递归之外的变量中。换句话说,没有存储在堆栈中。由于为此使用全局变量不是一个好主意,我们需要进行一些局部递归。
以下代码是一种愚蠢的方式来反转列表,但它确实说明了我所说的技术。
(define (letrecreverse lst)
(letrec ((retlist '())
(reverse (lambda (lst)
(if (null? lst)
'()
(begin
(set! retlist (cons (car lst) retlist))
(reverse (cdr lst)))))))
(reverse lst)
retlist))
(letrecreverse '(1 2 3 4))
;outputs '(4 3 2 1)
你可以为你的目的采用这种技术吗?